数据结构:双向链表

双向链表的概念:

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

双向链表的分类:

  • 不带头双向链表
  • 带头双向链表

示意图:

不带头双向链表:

详细代码请看:

https://blog.csdn.net/yanhuan136675/article/details/82766441


带头双向链表:(非循环)

dlist.h

#pragma once
 
typedef struct DNode
{
	int data;//数据域
	struct DNode *next;//后继指针
	struct DNode *prio;//前驱指针
}DNode,*DList;
 
//初始化双向链表
void InitDList(DList plist);
 
//头插
bool Insert_head(DList plist,int val);
 
//尾插
bool Insert_tail(DList plist,int val);
 
//查找
DNode *Search(DList plist,int key);
 
//删除
bool Delete(DList plist,int key);
 
//获取长度(数据结点的个数)
int GetLength(DList plist);
 
//判空
bool IsEmpty(DList plist);
 
//清空
void Clear(DList plist);
 
//摧毁
void Destroy(DList plist);
 
//打印
void Show(DList plist);
 
//逆置
void Reverse(DList plist);

dlist.cpp:

//初始化双向链表
void InitDList(DList plist)
{
    assert(plist != NULL);
	if(plist == NULL)
	{
		return ;
	}
 
	plist->next = NULL;
	plist->prio = NULL;

}
 
//头插
bool Insert_head(DList plist,int val)
{
    assert(plist != NULL);
	if(plist == NULL)
	{
		return false;
	}
 
	DNode *p = (DNode *)malloc(sizeof(DNode));
	p->data = val;
 
	p->next = plist->next;
	plist->next = p;
	p->prio = plist;
	if(p->next != NULL)
	{
		p->next->prio = p;
	}
	return true;
}
 
//尾插
bool Insert_tail(DList plist,int val)
{
    assert(plist != NULL);
	if(plist == NULL)
	{
		return false;
	}
 
	DNode *p = (DNode *)malloc(sizeof(DNode));
	p->data = val;
 
	DNode *q;
	for(q = plist;q->next != NULL;q = q->next);//找尾巴
 
	//将p插在q的后面
	p->next = q->next;
	q->next = p;	
	p->prio = q;
 
	return true;
}
 
//查找
DNode *Search(DList plist,int key)
{
    assert(plist != NULL);
	if(plist == NULL)
	{
		return false;
	}
 
	for(DNode *p = plist->next;p != NULL;p = p->next)
	{
		if(p->data == key)
		{
			return p;
		}
	}
	return NULL;
}
 
//删除
bool Delete(DList plist,int key)
{
    assert(plist != NULL);
	if(plist == NULL)
	{
		return false;
	}
 
	DNode *p = Search(plist,key);
	if(p == NULL)
	{
		return false;
	}
 
	p->prio->next = p->next;
	if(p->next != NULL)
	{
		p->next->prio = p->prio;
	}
	free(p);
 
	return true;  
}

//获取长度(数据结点的个数)
int GetLength(DList plist)
{
    int count = 0;
	for(DNode *p = plist->next;p != NULL;p = p->next)
	{
		count++;
	}
	return count;
}
 
//判空
bool IsEmpty(DList plist)
{
    return plist->next == NULL;
}
 
//清空
void Clear(DList plist)
{
    Destroy(plist);
}
 
//摧毁
void Destroy(DList plist)
{
    DNode *p;
	while(plist->next != NULL)
	{
		p = plist->next;
		plist->next = p->next;
		free(p);
	}

}
 
//打印
void Show(DList plist)
{
    for(DNode *p = plist->next;p != NULL;p = p->next)
	{
		printf("%d ",p->data);
	}
	printf("\n");

}
 
//逆置
void Reverse(DList plist)
{
	DNode *p = plist->next;
	DNode *q;
	int tmp;
 
	for(q = plist;q->next != NULL;q = q->next);//找尾巴
	
	  for(int i = 0;i < GetLength(plist)/2;i++)
		{
			tmp = p->data;
			p->data = q->data;
			q->data = tmp;
			p = p->next;
			q = q->prio;
		}
}

主函数:

扫描二维码关注公众号,回复: 8687385 查看本文章
#include<stdio.h>
#include<vld.h>//测试内存泄漏的头文件
#include"dlist.h"
 
int main()
{
	DNode head1;
	DNode head2;
	InitDList(&head1);
	InitDList(&head2);
	for(int i = 0;i < 10;i++)
	{
		Insert_head(&head1,i);
		Insert_tail(&head2,i);
	}
	Show(&head1);
	Show(&head2);
 
	printf("%d\n",Delete(&head1,3));
 
	printf("%d\n",GetLength(&head2));
 
	Destroy(&head1);
	Destroy(&head1);
 
	Reverse(&head2);
	Show(&head2);
 
	return 0;
}
发布了104 篇原创文章 · 获赞 15 · 访问量 7784

猜你喜欢

转载自blog.csdn.net/Kobe51920/article/details/103845933