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

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

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

1、表的简单数组实现

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

#define N 10
typedef 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->next;
	head->next = NULL;
	temp = NULL;
	return 0;

}





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值