数据结构(初阶 四)双向链表的实现

双向链表的实现

1.双向链表的定义

typedef int LTDataType;
typedef struct ListNode
{
    
    
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
}LTNode;

2.双向链表的初始化

 LTNode* ListInit()
 {
    
    
 	LTNode* node =(LTNode*)malloc(sizeof(LTNode));
 	if(guard==NULL)
 	{
    
    
 		perror("malloc fail");
     	exit(-1);
 	}
 	guard->next=guard;
 	guatd->prev=guard;

   return guard;
 }

3. 创建节点


LTNode* BuyListNode(LTDataType x)
{
    
    
	LTNode* node =(LTNode*)malloc(sizeof(LTNode));
 	if(guard==NULL)
 	{
    
    
 		perror("malloc fail");
     	exit(-1);
 	}
 	node->next=NULL;
 	node->prev=NULL;
 	node->data=x;
}

4.双向链表的尾插

在这里插入图片描述

void ListPushBack(LTNode* phead,LTDataType x)
{
    
    
    	assert(phead);
    	LTNode* newnode=BuyListNode(x);
    	LTNode* tail=phead->prev;
    	
   		tail->next=newnode;
   		newnode->prev=tail;
   		newnode->next=phead;
   		phead->prev=newnode;
}

5.双向链表的打印

   void ListPrint(LTNode* phead)
  {
    
    
  	assert(phead);
  	LTNode*cur=phead->next;
  	while(cur!=phead)
  	{
    
    
  		printf("phead<=>",cur->data);
  		cur=cur->next;
  	}
  	printf("\n");
   
}

6. 双向链表的头插

在这里插入图片描述

 void ListPushFront(LTNode* phead,LTDataType x)
{
    
    
  assert(phead);
  //先链接newnode和phead->next节点之间的关系
  
  //LTNode*newnode=ButListNode(x);
  //phead->next=phead->next;
  //phead->next->prev=newnode;

  //phead->next=newnode;
  //newnode->prev=phead;

  //不关心顺序
  
  LTNode* newnode=BuyListNode(x);
  LTNode* first=phead->next;
  phead->next=newnode;
  newnode->prev=phead;
  newnode->next=first;
  first->prev=newnode;
}

7. 双向链表的尾删

 void ListPopBack(LTNode*phead)
 {
    
    
	assert(phead);
	assert(!ListEmpty(phead);
	
	LTNode* tail=phead->prev;
	LTNode* prev=tail->prev;
	
	prev->next=pheadl;
	phead->prev=prev;
	free(tail); 
	tail=NULL;
}

8. 双向链表的头删

在这里插入图片描述

void ListPopFront(LTNode* phead)
{
    
    
	assert(phead);
	assert(!ListEmpry(phead));
	LTNode* frist=phead->next;
	LTNode* second =first->next;

	phead->next=second;
	second->prev=phead;
	
	free(first);
	first=NULL;
}

9. 判断是否为空链表

bool ListEmpty(LTNode* phead)
{
    
    
	assert(phead);
	return phead->next==phead;
}

10. 计算链表长度

size_t ListSize(LTNode* phead)
{
    
    
	assert(phead);
	size_t n=0;
	LTNode* cur=phead->next;
	while(cur!=phead)
	{
    
    
		++n;
		cur=cur->next;
	}
	return n;
}

11. 查找

ListNode* ListFind(LTNode* phead,LTDataType x)
{
    
    
	size_t n=0;
	LTNode* cur=phead->next;
	while(cur!=phead)
	{
    
    
		if(cur->data==x)
		{
    
    
			return cur;
		}
		cur=cur->next;
	}
	return NULL;
}

12. 任意节点插入

在这里插入图片描述

// 在pos之前插入
void ListInsert(LTNode* pos,LTDataType x)
{
    
     
	assert(pos);
	LTNode* prev=pos->prev;
	LTNode* newnode=BuyListNode(x);

	prev->next=newnode;
	newnode->prev= prev;
	newnode->next=pos;
	pos->prev=newnode;
}

13. 删除pos位置

在这里插入图片描述

void ListErase(LTNode* pos)
{
    
    
	assert(pos);
	LTNode* prev=pos->prev;
	LTNode* next=pos->prev;

	prev->next=next;
	next->prev=prev;
	free(pos);
	pos=NULL;
}

14. 销毁

// 可以传二级指针,内部置空头节点
// 建议:也可以考虑用一级指针,让调用ListDestory的人置空
void ListDestory(LTNode* phead)
{
    
    
	assert(phead);
	LTNode* cur=phead->next;
	while(cur!=phead)
	{
    
    
		LTNode* next=cur->next;
		free(cur);
		cur=next;
	}
	free(phead);
}

猜你喜欢

转载自blog.csdn.net/qq_45559559/article/details/126315634