带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
数据域data,指针域中包括指向前面节点的前驱指针prev,指向后面的后驱指针next
代码如下:
typedef struct ListNode
{
LTDataType data;
struct ListNode* next;
struct ListNode* prev;
};
代码如下:
struct ListNode* BuyListNode(LTDataType x)
{
struct ListNode* Node = (struct ListNode*)malloc(sizeof(struct ListNode));
Node->next = NULL;
Node->prev = NULL;
Node->data = x;
return Node;
}
代码如下:
struct ListNode* ListInit()
{
struct ListNode* phead = BuyListNode(0);
phead->next = phead;
phead->prev = phead;
return phead;
}
代码如下:
void ListPushBack(struct ListNode* phead, LTDataType x)
{
assert(phead);
struct ListNode* tail = phead->prev;
struct ListNode* newnode = BuyListNode(x);
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
}
代码如下:
void ListPushFront(struct ListNode* phead, LTDataType x)
{
assert(phead);
struct ListNode* newnode = BuyListNode(x);
struct ListNode* first = phead->next;
phead->next = newnode;
newnode->prev = phead;
newnode->next = first;
first->prev = newnode;
}
代码如下:
void ListPopBack(struct ListNode* phead)
{
assert(phead);
assert(phead != phead->next);
struct ListNode* tail = phead->prev;
struct ListNode* second = tail->prev;
free(tail);
tail = NULL;
second->next = phead;
phead->prev = second;
}
代码如下:
void ListPopFront(struct ListNode* phead)
{
assert(phead);
assert(phead != phead->next);
struct ListNode* first = phead->next;
struct ListNode* firstNext = first->next;
free(first);
first = NULL;
phead->next = firstNext;
first->prev = phead;
}
代码如下:
struct ListNode* ListFind(struct ListNode* phead, LTDataType x)
{
assert(phead);
struct ListNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
代码如下:
void ListInsert(struct ListNode* pos, LTDataType x)
{
assert(pos);
struct ListNode* newnode = BuyListNode(x);
struct ListNode* prev = pos->prev;
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
代码如下:
void ListEarse(struct ListNode* pos)
{
assert(pos);
struct ListNode* prev = pos->prev;
struct ListNode* next = pos->next;
prev->next = next;
next->prev = prev;
free(pos);
pos = NULL;
}
代码如下:
int ListEmpty(struct ListNode* phead)
{
assert(phead);
return phead->next == phead ? 1 : 0;
}
代码如下:
int ListSize(struct ListNode* phead)
{
assert(phead);
int size = 0;
struct ListNode* cur = phead->next;
while (cur != phead)
{
size++;
cur = cur->next;
}
return size;
}
代码如下:
void ListDestory(struct ListNode* phead)
{
assert(phead);
struct ListNode* cur = phead->next;
while (cur != phead)
{
struct ListNode* next = cur->next;
free(cur);
cur = next;
}
free(phead);
phead = NULL;
}
代码如下:
void ListPrint(struct ListNode* phead)
{
assert(phead);
struct ListNode* cur = phead->next;
while (cur != phead)
{
printf("%d-->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
以上就是今天要讲的内容,本文仅仅简单介绍了双向带头循环链表的使用,带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,我们务必掌握。另外,如果有需要源码的私信我即可。还有,,如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。
转码: 复制代码 代码如下: a.href="./showCont.jsp?tcontent="+encodeURI(encod...
Linux不像windows有那么显眼的回收站,不是简单的还原就可以了。linux删除文件还...
1.strcpy函数 原型声明char strcpy(char dest, const char *src); 头文件#includ...
前言 在创建对象需要初始化数据,数据参数不容易区别,可传可不传的时候,可以考...
前言 本文主要给大家介绍了关于WebSocket部署服务器外网无法连接的相关内容,分...
戳蓝字“ CSDN云计算 ”关注我们哦 作者 |?江子抑 转自 |?编程拯救世界 ? 主要思...
这是我正在写的博文系列中的另一篇,涵盖ASP.NET MVC 3的一些新功能: http://web...
AndroidXML 和 TotalCross 的运用为树莓派和其他设备创建 UI 提供了更简单的方法...
一、前言 对于初学者来说,要执行JSP和Servlet,Tomcat是一个很不错的选择。你也...
项目开发中,如果有定时任务的业务要求,我们会使用linux的crontab来解决,但是...