C语言数据结构创建及遍历十字链表

C语言数据结构创建及遍历十字链表

什么是十字链表

十字链表是一种二维数据结构,常用于表示稀疏矩阵,它是在链式储存结构的基础上,将正反两个方向都链起来,形成一个交叉的链表。

十字链表的创建

在创建十字链表时,我们需要定义两种结构:

//行结点
typedef struct CrossRowNode{
    int row; //行下标
    int col; //列下标
    int value; //具体值
    struct CrossRowNode *right, *down; //右指针和下指针
} CRNODE, *CRPTR;

// 列头结点
typedef struct CrossColHead{
    int colIndex; // 列下标
    struct CrossColHead *next; //下一个列头结点
    CRPTR bottom; //该列第一个非零元素所在的行结点
} CHEAD, *CHPTR;

其中,CRNODE表示十字链表中的行结点,CHEAD表示列头结点,CRPTR表示CrossRowNode的指针,CHPTR表示CrossColHead的指针。

我们可以通过输入稀疏矩阵的行数和列数,以及非零元素的个数,来初始化一个十字链表:

#include <stdio.h>
#include <stdlib.h>

// 初始化一个十字链表
void initCrossList(int row, int col, int count, int data[][3], CHPTR *chead){
    int i, j, k;
    CRPTR p, last;
    // 创建列头结点
    for(i = 0; i < col; ++i){
        CHPTR head = (CHPTR)malloc(sizeof(CHEAD));
        head->colIndex = i;
        head->next = NULL;
        head->bottom = NULL;
        (*chead)->next = head;
        *chead = head;
    }
    // 创建行结点
    for(k = 0; k < count; ++k){
        i = data[k][0];
        j = data[k][1];
        // 创建一个新结点
        p = (CRPTR)malloc(sizeof(CRNODE));
        p->row = i;
        p->col = j;
        p->value = data[k][2];
        // 找到该元素所在的列头结点
        last = (*chead)->next;
        while(last->colIndex < j) last = last->next;
        // 找到该元素的上一个结点
        CRPTR pre = last->bottom;
        while(pre && pre->row < i){
            last = pre;
            pre = pre->down;
        }
        // 将新结点插入到链表中
        if(last->bottom == NULL){
            last->bottom = p;
            p->down = NULL;
        } else {
            p->down = last->bottom->down;
            last->bottom->down = p;
        }
        // 找到该元素所在的行头结点
        last = (*chead)->next;
        while(last->colIndex < j) last = last->next;
        // 找到该元素的上一个结点
        pre = last;
        while(pre->bottom != NULL && pre->bottom->row < i) pre = pre->bottom;
        // 将新结点插入到链表中
        if(pre->bottom == NULL){
            pre->bottom = p;
            p->right = NULL;
        } else {
            p->right = pre->bottom->right;
            pre->bottom->right = p;
        }
    }
}

示例:

假设我们有一个3行4列的稀疏矩阵:

1 0 0 0
0 0 0 2
3 0 4 0

将其转换成十字链表,可以这样调用函数:

int data[4][3] = {{0, 0, 1}, {1, 3, 2}, {2, 0, 3}, {2, 2, 4}};
int row = 3, col = 4, count = 4;
CHPTR head = (CHPTR)malloc(sizeof(CHEAD));
initCrossList(row, col, count, data, &head);

十字链表的遍历

遍历十字链表的方式有多种,这里介绍两种比较常用的遍历方式。

按照行优先顺序遍历

按照行优先顺序遍历十字链表是比较常用的一种方式,具体实现可以使用嵌套循环来实现。

// 按照行优先顺序遍历十字链表
void travelByRow(CHPTR head){
    CRPTR node;
    for(node = head->bottom; node != NULL; node = node->down){
        printf("%d %d %d\n", node->row, node->col, node->value);
        CRPTR next = node->right;
        while(next != NULL){
            printf("%d %d %d\n", next->row, next->col, next->value);
            next = next->right;
        }
    }
}

示例:

假设我们有一个3行4列的十字链表,内容与之前的矩阵相同,我们可以按照以下方式遍历该链表:

travelByRow(head);

输出结果为:

0 0 1
1 3 2
2 0 3
2 2 4

按照行优先顺序遍历

按照列优先顺序遍历十字链表也是比较常用的一种方式,具体实现与行优先顺序遍历类似,只是循环的顺序相反。

// 按照列优先顺序遍历十字链表
void travelByCol(CHPTR head){
    CRPTR node;
    CHPTR chead = head->next;
    while(chead != NULL){
        node = chead->bottom;
        while(node != NULL){
            printf("%d %d %d\n", node->row, node->col, node->value);
            node = node->down;
        }
        chead = chead->next;
    }
}

示例:

与之前相同,假设我们有一个3行4列的十字链表,可以按照以下方式遍历该链表:

travelByCol(head);

输出结果为:

0 0 1
2 0 3
1 3 2
2 2 4

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构创建及遍历十字链表 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 详解Vue.js 作用域、slot用法(单个slot、具名slot)

    详解Vue.js 作用域、slot用法(单个slot、具名slot) Vue.js是一种流行的JavaScript框架,用于构建交互式的Web应用程序。在Vue.js中,作用域和slot是两个重要的概念,用于组件之间的通信和内容分发。 作用域 作用域是指在Vue组件中定义的变量或方法的可见范围。Vue组件中的作用域可以分为两种类型:全局作用域和局部作用域。 …

    other 2023年8月19日
    00
  • springboot配置文件中使用${}注入值的两种方式小结

    当我们在Spring Boot项目中编写配置文件时,我们会使用 ${} 语法来注入值以便让我们的应用程序可配置化。在这篇文章中,我将为大家介绍在Spring Boot配置文件中使用 ${} 语法注入值的两种方式,即在application.properties文件和application.yaml文件中使用。 在application.properties文…

    other 2023年6月25日
    00
  • GC参考手册二java中垃圾回收原理解析

    GC参考手册二:Java中垃圾回收原理解析 简介 本攻略将详细讲解Java中的垃圾回收原理,并提供两个示例来说明垃圾回收的过程。 垃圾回收原理 Java中的垃圾回收是自动进行的,它通过检测不再被引用的对象,并释放它们所占用的内存空间。垃圾回收器(Garbage Collector)是负责执行垃圾回收的组件。 Java中的垃圾回收原理基于以下两个核心概念: 引…

    other 2023年8月2日
    00
  • 根据IP地址查交换机端口

    根据IP地址查交换机端口攻略 要根据IP地址查找交换机端口,可以通过以下步骤进行操作: 确定目标交换机:首先,确定你要查找的目标交换机。这可能是你本地网络中的一台交换机,或者是你管理的远程网络中的一台交换机。 登录到交换机:使用适当的管理工具(如SSH或Telnet)登录到目标交换机。你需要具备相应的管理员权限才能执行这个操作。 进入特权模式:一旦登录到交换…

    other 2023年7月31日
    00
  • ScrollView嵌套ListView滑动冲突的解决方法

    ScrollView嵌套ListView滑动冲突的解决方法 当我们在Android开发中需要在一个ScrollView中嵌套一个ListView时,可能会遇到滑动冲突的问题。这是因为ScrollView和ListView都具有滑动功能,导致它们之间的滑动事件冲突。下面是解决这个问题的完整攻略。 方法一:自定义ListView 一种解决方法是自定义一个List…

    other 2023年7月28日
    00
  • Redis事务处理的使用操作方法

    以下是关于Redis事务处理的使用操作方法的完整攻略: 开启事务:使用MULTI命令来开启一个事务。事务中的所有命令都将被放入一个队列中,直到事务被执行。 示例说明1:开启事务 MULTI 2. **执行事务**:使用`EXEC`命令来执行事务中的所有命令。Redis会按照命令在队列中的顺序依次执行。 示例说明2:执行事务 “`markdown EXEC …

    other 2023年10月18日
    00
  • phpstorm怎么全局搜索

    以下是关于“PhpStorm如何进行全局搜索”的完整攻略: 步骤1:打开PhpStorm 首先,需要打开PhpStorm编辑器。 步骤2:打开全局搜索窗口 在PhpStorm中,可以使用以下快捷键打开全局搜索窗口: Windows和Linux系统:Ctrl + Shift + F macOS系统:Command + + F 也可以使用以下步骤打开全局搜索窗口…

    other 2023年5月7日
    00
  • 第一章:起步(python环境搭建)

    第一章:起步(python环境搭建) 为什么要搭建Python开发环境? Python是一门广泛使用的动态编程语言,用于各种开发工作,包括Web应用、桌面应用、网络爬虫、人工智能等。通过搭建Python开发环境,程序员可以更方便地进行Python开发。 Python开发环境搭建步骤 1.安装Python Python可以在其官方网站https://www.p…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部