Linux学习(十):数据结构--表

来源:互联网 发布:淘宝网平板电脑手机 编辑:程序博客网 时间:2024/06/08 06:16

本文讨论最简单最基本的一种数据结构:表。

我们将处理一般的形如A1,A2,A3.....AN的表。这个表的大小为N。我们称大小为0的表为空表。

1、表的简单数组实现

对表的所有操作都可以通过数组来实现。我们假定数据量为10个,所以我们可以设置一个有10个元素的数组。同时为了表示数组的位置,再定义一个表示数组位置的变量

#define N 10typedef int data_t;typedef struct{   data_t a[10];   int last;}sqlist;
用这个结构体我们可以实现一个简单的表。

1.1 数组表的创建

表的创建很简单,我们用一个指针来指向这个表,只要开辟响应的空间即可,并将数组位置last置为-1
sqlist *sqlist_creat(){  sqlist * sqlist_node = (sqlist *)malloc(sizeof(sqlist));  sqlist_node->last = -1;  return sqlist;}

1.2 添加

向表的最后添加一个数据

data_t sqlist_add_tail(sqlist *list,data_t value){list->a[list->last] = value;list->last++;}
但是,由于数组是有数量的,有可能出现满的情况,所以要先判断一下数组是否已经满加入到上面的函数中
int is_full(sqlist *list){return list->last == N-1?1:0;}data_t sqlist_add_tail(sqlist *list,data_t value){if(is_full(list)){printf("list is full\n");return -1;}list->last++;list->a[list->last] = value;return 0;}

1.3 删除一个元素
添加时要判断是为满,同样删除时候要先判断一下是否为空。
int is_empty(sqlist *list){return list->last == -1?1:0;}

删除元素,删除一个元素时,我们必须将其后面的元素依次往前移动。

data_t sqlist_delete(sqlist *list,data_t value){int i=0;int j = 0;if(is_empty(list)){printf("list is empty\n");return -1;}for(i=0;i<=list->last;i++){if(list->a[i] == value){for(j=i;j<list->last;j++){list->a[j] = list->a[j+1];}list->last--;}}return 0;}

上图就是删除元素11的情况,我们需要将后面的所有元素都往前移动,这实际上是很费劲的。同时,会想到另外一个问题,在某个位置插入元素时,需要这个位置及其后面的元素依次往后移动,这同样开销会很大。

2、链表

为了避免插入和删除的线性开销,我们可以使表不连续存储。为此我们可以设置这样的节点:一个数据,一个地址,地址指向下一个节点。

2.1 链表创建

定义以下变量
typedef int data_t;typedef struct node{data_t data;struct node * next;}link_node;

在创建链表时,我们先创建一个头节点head,这个节点没有数据,地址指向为NULL,这也就是单向链表。
link_node *list_creat(){link_node *head = (link_node *)malloc(sizeof(link_node));head->next = NULL;return head;}

2.2 链表添加

链表的添加分为头插入、尾插入和任意位置擦汗如,也就是新节点添加位置的区别。

2.2.1 头插入添加

头添加过程如下
首先将原先的第一个节点地址给要添加的节点,
然后将要添加的节点地址给头节点head
这两步不能反,先执行第二步会使得无法找到原来第一个节点了(当然你可以使用临时变量)。与数组表不同的是,链表不存在满的情况,所以不用判断是否为满。
int link_list_add(link_node *head,data_t value){link_node *node = (link_node *)malloc(sizeof(link_node));node->data = value;node->next = head->next;head->next = node;return 0;}

2.2.2 尾插入添加

尾插入的方法就是将新节点添加到链表的最后
将新添加的节点放到最后一个节点的后面,首先需要找到最后一个节点,可通过node->next是否为NULL来判断。

int link_list_add_tail(link_node *head, data_t value){link_node *node = (link_node *)malloc(sizeof(link_node));node->data = value;node->next = NULL;while(head->next!=NULL){head = head->next;}head->next = node;}

2.3 链表删除

与链表添加一样,删除也可以分为头删除和尾删除

2.3.1 头删除


删除前首先需要判断链表是否为空。头删除后要把不用的节点指向NULL防止野指针。
int is_empty(link_node *head){return head->next==NULL?1:0;}int link_list_del(link_node *head){if(is_empty(head)){printf("is empty\n");return -1;}link_node *temp = head->next;head->next = temp->next;temp = NULL;}

2.3.2 尾删除

尾删除是删除最后一个节点,所以要找到倒数第二个节点

int link_list_del_tail(link_node *head){link_node *temp = NULL;if(is_empty(head)){printf("is empty\n");return -1;}while(head->next->next!=NULL){head = head->next;}temp = head;head->next = NULL;temp = NULL;return 0;}





原创粉丝点击