0
点赞
收藏
分享

微信扫一扫

双向带头循环链表详解->附c语言创建链表代码

目录

一,双向带头循环链表是什么

二.双向带头循环链表的优缺点

三.怎样去创建双向带头循环链表

 四.具体代码


一,双向带头循环链表是什么

      定义: 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道 ,其具体实现过程如下图所示。

二.双向带头循环链表的优缺点

双向带头循环链表

优点:双向带头循环链表优点存在前驱与后继,即可以双向寻找

缺点:不支持下标随机访问

顺序表优缺点

优点: 相对而言空间利用率更高,不需要额外空间,占用空间小(链表需要存指针)。 物理空间是连续的。支持随机访问,可以用下标访问(最大优势);缓存命中率较高。

缺点: 头部或中间插入或删除数据,需要一个一个挪动,时间复杂度高,但空间复杂度小

.怎样去创建双向带头循环链表

1.首先需要创建结构体,然后创建头节点(相当于哨兵位),通过头节点去链接新节点

  typedef struct ListNode

{

       struct ListNode*prev;

       struct ListNode*next;

       LTDataType data;

}ListNode;

2.初始化节点(重点,需要考虑第一个节点作为头节点)

ListNode*ListInit()

{

   ListNode*phead=BuyListNode(0);//此时phead为哨兵位,作头节点

   phead->next=phead;

   phead->prev=phead;

          return phead;

}

3.创造节点

ListNode* BuyListNode(LTDataType x)

{

       ListNode*node=(ListNode*)malloc(sizeof(ListNode));

       node->next=NULL;

       node->prev=NULL;

       node->data=x;

       return node;

}//动态管理空间

4.插入数据(通过插入数据,也可实现头插和尾插,所以头插和尾插通过复用即可实现)

void ListInsert(ListNode*pos,LTDataType x)//插入数据

{

       assert(pos);

       ListNode*newnode=BuyListNode(x);

       ListNode*prev=pos->prev;

       prev->next=newnode;

       newnode->prev=prev;

       newnode->next=pos;

       pos->prev=newnode;

}

5.删除指定数据(相同,尾删和头删也可以通过复用来实现)

void ListErase(ListNode*pos)//删除指定位置数据

{

       assert(pos);

       ListNode*prev=pos->prev;

       ListNode*tail=pos->next;

       prev->next=tail;

       tail->prev=prev;

       free(pos);

}

6.销毁链表

  void ListDestory(ListNode* phead)

{

       ListNode*cur=phead->next;

       while(cur!=phead)//先释放内部节点

       {

              ListNode*next=cur->next;

              free(cur);  

              cur=next;

       }

       free(phead); //再释放头节点

}

 四.具体代码

   1.头文件

#include<stdio.h>
#include<assert.h>
#include<stdlib.h> 
#include<malloc.h>
typedef int LTDataType;
typedef struct ListNode
{
	struct ListNode*prev;
	struct ListNode*next;
	LTDataType data;
}ListNode;
ListNode* BuyListNode(LTDataType x);
ListNode* ListInit();
void ListPushBack(ListNode* phead,LTDataType x);
void ListPusnFront(ListNode* phead,LTDataType x);
void ListPrint(ListNode*phead); 
void ListpopBack(ListNode*phead);//尾删 
void ListPopFront(ListNode*phead);//头删 
void ListInsert(ListNode*pos,LTDataType x);//插入数据 
void ListErase(ListNode*pos);
void ListDestory(ListNode* phead);//销毁
LTDataType ListEmpty(ListNode* phead);//判断是否为空 
LTDataType ListFind(ListNode* phead,LTDataType x);

2.主函数模块 

#include"ListNode.h"
void Test()
{
    ListNode*plist=ListInit(0);	
    ListPushBack(plist,1);
    ListPushBack(plist,2);
	ListPushBack(plist,3);
	ListPushBack(plist,4);
	ListPushBack(plist,5);
	ListPushBack(plist,6);
	ListPusnFront(plist,88);
	ListpopBack(plist);
	ListPopFront(plist);
	ListInsert(plist->next->next,55);
	ListErase(plist->next->next);
    ListPrint(plist);
    LTDataType num=ListFind(plist,3);
    if(num==1)
    {
		printf("找到了\n"); 
	}
	else
	{
		printf("没有\n") ; 
	} 
	   LTDataType a=ListEmpty(plist); 
	     if(a==0)
	     {
		 	printf("空\n"); 
		 }
		 else
		 {
		 printf("非空\n");	
		} 
    //int nums=ListEmpty(plist);
    //printf("%d",nums);
}
int main()
{
	Test();
	return 0;
}

3.函数实现模块 

#include"ListNode.h"
ListNode* BuyListNode(LTDataType x)
{
	ListNode*node=(ListNode*)malloc(sizeof(ListNode));
	node->next=NULL;
	node->prev=NULL;
	node->data=x;
	return node;
}
ListNode*ListInit()
{
   ListNode*phead=BuyListNode(0);//此时phead为哨兵位,作头节点 
   phead->next=phead;
   phead->prev=phead;
   	return phead;
} 
void ListPushBack(ListNode*phead,LTDataType x)//尾插 
{
	/*assert(phead);
	ListNode*tail=phead->prev;
	ListNode*newnode=BuyListNode(x);
	tail->next=newnode;
	newnode->prev=tail;
	newnode->next=phead;
	phead->prev=newnode;*/ 
	ListInsert(phead,x);
}
void ListPusnFront(ListNode* phead,LTDataType x)//头插 
{
	/*assert(phead);
	ListNode*first=phead->next;
	ListNode*newnode=BuyListNode(x);
	first->prev=newnode;
    newnode->next=first;
    phead->next=newnode;
    newnode->prev=phead;*/
	ListInsert(phead->next,x);	
}
void ListPrint(ListNode*phead)
{
	ListNode*cur=phead->next;
	while(cur!=phead)
	{
		printf("%d ",cur->data);
		cur=cur->next;
	}
	printf("\n");
}
void ListpopBack(ListNode*phead)//尾删 
{
	assert(phead);
   /*ListNode*tail=phead->prev;
	ListNode*tailPrev=tail->prev;
	free(tail);
	tailPrev->next=phead;
	phead->prev=tailPrev;*/
	ListErase(phead->prev);
}
void ListPopFront(ListNode*phead)//头删 
{
    assert(phead);
	assert(phead->next!=phead);
	/*ListNode*first=phead->next;
	ListNode*firstnext=first->next;
	free(first);
	phead->next=firstnext;
	firstnext->prev=phead;*/
	ListErase(phead->next); 
}
void ListInsert(ListNode*pos,LTDataType x)//插入数据 
{
	assert(pos);
	ListNode*newnode=BuyListNode(x);
	ListNode*prev=pos->prev;
	prev->next=newnode;
	newnode->prev=prev;
	newnode->next=pos;
	pos->prev=newnode;
} 
void ListErase(ListNode*pos)//删除指定位置数据 
{
	assert(pos);
	ListNode*prev=pos->prev;
	ListNode*tail=pos->next;
	prev->next=tail;
	tail->prev=prev;
	free(pos);
}
void ListDestory(ListNode* phead)
{
	ListNode*cur=phead->next;
	while(cur!=phead)
	{
		ListNode*next=cur->next;
		free(cur);	
		cur=next;
	}
	free(phead); 
}
LTDataType  ListEmpty(ListNode* phead)//判断链表是否为空 
{
	if(phead->next==phead)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
LTDataType ListFind(ListNode* phead,LTDataType x)
{
	ListNode* cur=phead->next;
	while(cur!=phead)
	{
		if(cur->data==x)
		{
			return 1; 
		}
		cur=cur->next;
	}
	return 0;
}
举报

相关推荐

0 条评论