数据结构之链式表的实现--双向链表(C语言)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40411915/article/details/82718654

 学习参考: 严蔚敏: 《数据结构-C语言版》

-----单链表类似,双链表一般也是由头指针唯一确定的,增加头指针也能使双链表上的某些运算变得方便,将头结点和尾结点链接起来也能构成循环链表,并称之为双向链表。

双向链表的基本操作

  1. 双向链表的建立
  2. 双向链表添加结点(头插法)
  3. 双向链表添加结点(尾插法)
  4. 双向链表的输出
  5. 双向链表的插入
  6. 双向链表的删除
  7. 双向链表按序号查找
  8. 双向链表按值查找 
  9. 双向链表销毁
  10. 双向链表的长度

基本操作代码实现

双向链表的结点定义

typedef struct node
{
	struct node* next;
	struct node* prior;
	int data;
}* pNode, Node;

双向链表的结构定义

typedef struct 
{
	pNode node;
	int len;
}DoubleList,* pDList;

 双向链表的建立

int initDoubleList(pDList list)
{
	if(!list)
		return 0;
	list->len = 0;
	list->node = NULL;
	return 1;
}

双向链表添加结点(头插法)

int addDataHead(pDList list, int data)
{
	pNode q = NULL, p = NULL;
	if(!list)
		return 0;
	p = list->node;
	q = (pNode)malloc(sizeof(Node));
	if(!q)
		return 0;
	q->data = data;
	if(!p)
	{
		q->next = NULL;
		list->node = q;
		q->prior = NULL;
	}
	else
	{
		list->node = q;
		q->next = p;
		p->prior = q;
		q->prior = NULL;
	}
	list->len++;
	return 1;
}

双向链表添加结点(尾插法)

int addDataTail(pDList list, int data)
{
	pNode pre = NULL, p = NULL;
	if(!list)
		return 0;
	p = list->node;
	while(p)
	{
		pre = p;
		p=p->next;
	}
	p = (pNode)malloc(sizeof(Node));
	if(!p)
		return 0;
	p->next = NULL;
	p->data = data;
	if(!pre)
	{
		list->node = p;
		p->prior = NULL;
	}
	else
	{
		p->prior = pre;
		pre->next = p;
	}
	list->len ++;
	return 1;
}

双向链表的输出

int display(pDList list)
{
	pNode p = NULL;
	if(!list->node)
		return 0;
	p = list->node;
	while(p)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
	return 1;
}

双向链表的插入

int insertData(pDList list, int pos, int data)
{
	pNode LacNode = NULL, p = NULL;
	int count = 1;
	if(!list || pos<1 || pos>list->len+1)
		return 0;
	LacNode = list->node;
	while( count<pos)
	{
		count++;
		LacNode = LacNode->next;
	}
	if(!LacNode)
	{
		addDataTail(list, data);
		return 1;
	}
	p = (pNode)malloc(sizeof(Node));
	p->data = data;
	p->prior = LacNode->prior;
	LacNode->prior->next = p;
	LacNode->prior = p;
	p->next = LacNode;
	list->len++;
	return 1;
}

双向链表的删除

int deleteData(pDList list, int pos, int* data)
{
	pNode LacNode = NULL, p = NULL;
	int count = 1;
	if(!list || !list->node || pos<1 || pos>list->len+1)
		return 0;
	LacNode = list->node;
	while(count<pos)
	{
		count++;
		LacNode = LacNode->next;
	}
	if(count==1)
	{
		*data = LacNode->data;
		free(LacNode);
		LacNode = NULL;
		list->node = NULL;
	}
	else if(count==list->len)
	{
		LacNode->prior->next = NULL;
		*data = LacNode->data;
		free(LacNode);
		LacNode = NULL;
	}else
	{
		LacNode->next->prior = LacNode->prior;
		LacNode->prior->next = LacNode->next;
		*data = LacNode->data;
		free(LacNode);
		LacNode = NULL;
	}
	list->len --;
	return 1;
}

双向链表按序号查找

int getData(pDList list, int pos, int* data)
{	
	pNode p = NULL;
	int count = 1;
	if(!list || pos<1 || pos >list->len || !list->node)
	{
        *data = -1;
    	return 0;
	}
	p = list->node;
	while( count<pos)
	{
		count++;
		p = p->next;
	}
	*data = p->data;
	return 1;
}

双向链表按值查找 

int getLacate(pDList list, int data, int* index)
{
		pNode p = NULL;
	int count = 0;
	if(!list || !list->node)
	{
        *index = -1;
    	return 0;
	}
	p = list->node;
	while(p)
	{
		count++;
		if(p->data == data)
			break;
		p = p->next;
	}
	if(!p)
	{
		*index = -1;
		return 0;
	}
	*index = count;
	return 1;
}

双向链表销毁

int destroyData(pDList list)
{
	pNode pre = NULL, p = NULL;
	if(!list || !list->node)
		return 0;
	p = list->node;
	while(p)
	{
		pre = p;
		p = pre->next;
		free(pre);
		pre = NULL;
	}
	list->len =0;
	list->node =NULL;
	return 1;
}

双向链表的长度

int getLength(pDList list, int* len)
{
	if(!list)
		return 0;
	*len = list->len;
	return 1;
}

测试代码

#include <stdio.h>
#include "DoubleList.h"

int main()
{
	DoubleList list;
	int val = -1;
	int i = 1;
	initDoubleList(&list);
	for(i; i<6; ++i)
		addDataHead(&list, i);
	display(&list);
	for(i=11; i<16; ++i)
		addDataTail(&list, i);
	for(i; i<6; ++i)
		insertData(&list, i, i);
	display(&list);
	deleteData(&list, 2, &val);
	printf("%d...\n", val);
	display(&list);
	getData(&list, 5, &val);
	printf("第5个位置上的数字: %d...\n", val);
	getLacate(&list, 11, &val);
	printf("11号位置为: %d...\n", val);
	display(&list);
	destroyData(&list);
	display(&list);
	return 0;
}

 写在最后

 文章记录本人学习所得, 如有所错误, 欢迎留言指出交流, 大神请键盘下留人 ! ! !

猜你喜欢

转载自blog.csdn.net/weixin_40411915/article/details/82718654