欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线性表之单链表

程序员文章站 2022-06-06 13:38:55
...

线性表的链式存储结构


下面讨论线性表的链式存储结构,即链表。
单链表的结构
将线性表L=(a0,a1,a2…,an-1)中各元素分布在不同存储器的不同存储块,称为结点,通过地址或指针 建立它们之间的联系,所得到的存储结构为链表结构。其中,节点的data域存放数据元素,而next域是一个指针,指向ai的直接后继ai+1所在的结点。于是结点和线性表的结构如下图:

线性表之单链表


单链表的基本运算


1.结点的描述:
代码实现

typedef int datatype;
typedef struct node
{
	datatype data;
	struct node* next;
}listnode,*linklist;

2.头结点的创建


代码实现

linklist Firstnode_create()
{
	linklist H = NULL;
	H = (linklist)malloc(sizeof(listnode));
	if(H == NULL)
	{
		printf("malloc faild.");
		return NULL;
	}
	H->data = 0;					
	H->next = NULL;
	return H;
}

3.单链表的创建*


算法思路:依次读入结点中每一个元素ai(假设为int型),若ai != 结束符(-1),则创建一个结点,然后插入表尾,最后返回链表的 头结点指针H。
线性表之单链表
代码实现

linklist list_create()
{
	linklist H=NULL;
	linklist r=NULL;

	int value;
	H = (linklist)malloc(sizeof(listnode));
	if(H == NULL)
	{
		printf("malloc faild.");
		return NULL;
	}
	H->data = value;
	H->next =NULL;
	r = H;
	linklist P=NULL;
	while(1)
	{
		printf("input a number(-1 exit):");
		scanf("%d",&value);
		if(value == -1)
		{
			break;
		}

		P = (linklist)malloc(sizeof(listnode));
		if(NULL == P)
		{
			printf("malloc failed.\n");
			return H;
		}
		P->data = value;
		P->next = NULL;
		r->next = P;
		r = P;
	}
	return H;
}


4.链表的遍历


算法思路:当遍历查找结点的指针域为NULL时结束遍历。
代码实现

void list_show(linklist H)
{
	while(H->next)
	{
		printf("%d\n",H->next->data);
		H = H->next;
	}
	printf("\n");
}

5.链表的按序号查找


算法思路:从链表的a0起,判断是否为第pos结点,若是则返回该节点的指针,否则查找下一结点,以此类推。
代码实现

linklist list_get(linklist H,int pos)
{
	linklist P = H;
	int i = -1;
	if(pos < 0)                                //判断输入的位置是否合理
	{
		printf("position is invalid:<0\n");
		return NULL;
	}
	while(P->next && i < pos)
	{
		P = P->next;
		i++;
	}
	if(i==pos)
	{
		return P;
	}
	else
	{
		printf("position is invalid:>length\n");
		return NULL;
	}
}

6.链表的按值查找


算法思路:从链表的a0起,判断某结点是否等于value,若是则返回该节点的指针,否则查找下一结点,以此类推。
实现代码

linklist list_get_value(linklist H,datatype value)
{
	linklist P = H->next;
	while(P && P->data!= value)
	{
		P = P->next;
	}
	return P;
}

7.链表的头插入算法


算法思路

线性表之单链表
实现代码

int list_head_insert(linklist H,datatype value)
{
	linklist P = NULL;
	P = (linklist)malloc(sizeof(listnode));
	if(P == NULL)
	{
		printf("malloc failed\n");
		return -1;
	}
	P->data = value;
	P->next = H->next;
	H->next = P;
	return 0;
}

8.上面第三点链表的创建就是链表的尾插入,这里就不在累赘。



9.链表的按位置插入


算法思路:调用算法list_get(linklist H,int pos),获取结点要插入的位置的ai的前驱a (i-1),然后申请一个结点,存入x,并将其插入P指向的结点之后。

线性表之单链表

代码实现

int list_local_insert(linklist H,int pos,datatype value)
{
	linklist p,q;
	if(pos == 0)
	{
		p = H;
	}
	else
	{
		p = list_get(H,pos-1);
	}
	if(p == NULL)
	{
		printf("para is invalid\n");
		return -1;
	}
	else
	{
		q = (linklist)malloc(sizeof(listnode));
		if(q == NULL)
		{
			printf("malloc failed\n");
			return -1;
		}
		q->data = value;
		q->next = p->next;
		p->next = q;
		return 0;
	}
}

10.链表的有序插入


算法思路:类似按位置插入算法,只是通过比较传入的value选择插入的位置。
代码实现

int list_order_insert(linklist H,datatype value)
{
	linklist p,q;
	p = (linklist)malloc(sizeof(listnode));
	if(p == NULL)
	{
		printf("malloc failed\n");
		return -1;
	}
	p->data = value;
	q = H;
	while(q->next &&q->next->data < value)
	{
		q = q->next;
	}
	p->next = q->next;
	q->next = p;
	return 0;
}

11.链表结点的删除


算法思路:同插入法,先调用函数list_get(H,pos-1);获取ai的前驱ai-1,然后定义一个指针变量q指向要删除的ai结点,指针变量P指向那个ai的前驱,然后将ai结点删除即可。

代码实现

int list_delete(linklist H,int pos)
{
	linklist p,q;
	if(pos == 0)
	{
		p = H;
	}
	else
	{
		p = list_get(H,pos-1);
	}
	if(p == NULL)
	{
		printf("para is failed\n");
		return -1;
	}
	else
	{
		q = p->next;
		p->next = q->next;
		free(q);
		q = NULL;
		return 0;
	}
}

12.单链表的倒置


算法思路:先把链表一分为二,依次为头结点和剩下的结点(剩下的结点用指针P指向),依次取P指向的链表中的各个结点,并将其作为新链表首结点插入H结点之后。

线性表之单链表

代码实现

void list_reverse(linklist H)
{
	linklist p,q;
	p = H->next;         //将头结点根剩下的结点一分为二
	H->next = NULL;
	while(p)
	{
		q = p;               //把P赋值给q来操作
		p = p->next;         //依次往下取各个结点
		
		q->next = H->next;   //头插入法插入头结点
		H->next = q;
	}
}

13.链表的排序


算法思路

线性表之单链表

代码实现

void list_sort(linklist H)
{
	linklist p,q,r;
	p = H->next;
	H->next = NULL;

	while(p)
	{
		q = p;
		p = p->next;
		r = H;
		while(r->next && r->next->data < q->data)
		{
			r = r->next;
		}
		q->next = r->next;
		r->next = q;
	}
}