当前位置: 首页 > news >正文

网站后台怎样推荐图片哈尔滨优化调整人员流动管理

网站后台怎样推荐图片,哈尔滨优化调整人员流动管理,工业软件开发技术专业,如何做合作社网站详解C语言动态实现带头结点的双向循环链表结构~😎前言🙌预备小知识💞链表的概念及结构🙌预备小知识💞链表的概念及结构🙌带头结点的双向循环链表结构🙌整体实现内容分析💞1.头文件编…

详解C语言动态实现带头结点的双向循环链表结构~😎

  • 前言🙌
  • 预备小知识💞
    • 链表的概念及结构🙌
  • 预备小知识💞
    • 链表的概念及结构🙌
    • 带头结点的双向循环链表结构🙌
  • 整体实现内容分析💞
  • 1.头文件编码实现🙌
  • 2.代码功能实现🙌
    • 1)这是生成新节点函数实现。😊
    • 2)生成带头结点的空链表函数实现。😊
    • 3)删除链表函数实现。😊
    • 4)顺序输出链表函数实现。😊
    • 5)尾插函数实现。😊
    • 6)头插函数实现。😊
    • 7)头删函数实现。😊
    • 8)尾删函数的实现。😊
    • 9)查找函数实现。😊
    • 10)pos位置之前插入x的函数实现。😊
    • 11)删除pos位置的值的函数实现。😊
    • 12)逆序输出的函数实现。😊
    • 13)判空函数实现。😊
  • 3.测试文件源码分享:🙌
  • 总结撒花💞

追梦之旅,你我同行

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
在这里插入图片描述

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下!😘我仅已此文,手把手带领大家学习C语言动态实现实现带头结点的双向循环链表结构~ 用代码来实现一个带头结点的双向循环链表结构,完成增删查改,顺序输出和逆序输出,判空的功能。都是精华内容,可不要错过哟!!!😍😍😍

预备小知识💞

链表的概念及结构🙌

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的 。

预备小知识💞

链表的概念及结构🙌

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的 。

在这里插入图片描述

带头结点的双向循环链表结构🙌

在这里插入图片描述带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了

整体实现内容分析💞

首先在头文件先定义结构体和各个功能函数的声明,并把有关的头文件包含上去。各个函数如何实现的,已在实验步骤描述清楚,这里就不在赘述了,主要是对各个函数的实现,用到malloc动态开辟新节点的空间,用assert断言确保指针有效,通过画图来帮助理清代码实现的思路,指针的指向如何,要考虑哪些情况。然后再测试代码中,将上述代码都进行测试,显示结果。

1.头文件编码实现🙌

12、	#pragma once
3、	#include <stdio.h>
4、	#include <stdlib.h>
5、	#include <assert.h>
6、	#include <stdbool.h>
78typedef int LTDataType;
9// 带头双向循环链表结构体
10typedef struct ListNode
11{
12struct ListNode* next;
13struct ListNode* prev;
14、		LTDataType data;
15}ListNode;
16、	ListNode* ListInit();//链表初始化
17void ListDestory(ListNode* phead);//删除链表
18void ListPrintFront(ListNode* phead);//链表顺序输出
19void ListPrintBack(ListNode* phead);//链表逆序输出
20void ListPushBack(ListNode* phead, LTDataType x);//尾插
21void ListPushFront(ListNode* phead, LTDataType x);//头插
22void ListPopFront(ListNode* phead);//头删
23void ListPopBack(ListNode* phead);//尾删
24、	ListNode* ListFind(ListNode* phead, LTDataType x);//查找
25void ListInsert(ListNode* pos, LTDataType x);// pos位置之前插入x
26void ListErase(ListNode* pos);// 删除pos位置的值
27、	bool ListEmpty(ListNode* phead);判空函数

2.代码功能实现🙌

1)这是生成新节点函数实现。😊

代码实现思路详解:

//用malloc动态开辟新节点的空间,把数值赋值给新节点
//,newnode的next和prev指针指向空。

ListNode* BuyListNode(LTDataType x)
{ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));newnode->data = x;newnode->next = NULL;newnode->prev = NULL;return newnode;
}

2)生成带头结点的空链表函数实现。😊

代码实现思路详解:

//2)生成带头结点的空链表,将头结点的指针都指向自己即可。

ListNode* ListInit()
{ListNode* phead = BuyListNode(0);phead->next = phead;phead->prev = phead;return phead;
}

3)删除链表函数实现。😊

代码实现思路详解:

//3)先用assert断言以下确保phead指针不为空,生成cur指针先指向第一个结点位置。用while循环执行删表:在定义一个next指针指向cur的下一个结点,free掉cur指向的结点,cur移动到next位置。最后删除头结点即可
//


void ListDestory(ListNode* phead)//删除链表
{assert(phead);ListNode* cur = phead->next;while (cur != phead){ListNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}

4)顺序输出链表函数实现。😊

代码实现思路详解:

//4)顺序输出链表。先assert断言确保指针有效。定义一个指向链表首结点的指针,打印完一个,cur到下一个节点知道cur回到phead为止。

void ListPrintFront(ListNode* phead)
{assert(phead);ListNode* cur = phead->next;while (cur != phead){printf("%d ", cur->data);cur = cur->next;}printf("\n");
}

5)尾插函数实现。😊

代码实现思路详解:

//5)尾插函数。先assert确保指针有效性,定义tail指针指向最后一个节点,然后生成新节点然后通过指针将tail指向的节点与新生成的节点相连,新生成的节点与哨兵位头结点相连


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;
}

6)头插函数实现。😊

代码实现思路详解:

//6)头插函数实现。先assert断言一下确保传入进来的指针有效。定义一个指向首节点的指针然后生成一个新节点,让新节点与头结点相连,让新节点的next指针指向原来首节点,原来首节点的prev指向新节点让新节点位于原来首节点的前面从而实现头插。

void ListPushFront(ListNode* phead, LTDataType x)
{assert(phead);ListNode* first = phead->next;ListNode* newnode = BuyListNode(x);phead->next = newnode;newnode->prev = phead;newnode->next = first;first->prev = newnode;
}

7)头删函数实现。😊

代码实现思路详解:

//7)头删函数实现。assert确保传入指针有效和确保头结点不要被删掉。定义first指针指向链表首节点,second指向first下一个。然后让头结点与second指针指向的节点相连,然后free掉first指向的节点。


void ListPopFront(ListNode* phead)
{assert(phead);assert(phead->next != phead);ListNode* first = phead->next;ListNode* second = first->next;phead->next = second;second->prev = phead;free(first);first = NULL;}

8)尾删函数的实现。😊

代码实现思路详解:

//8)尾删函数的实现。头删函数实现。assert确保传入指针有效和确保头结点不要被删掉。定义tail函数指向尾节点,定义prev指针指向tail的前一个节点,让prev指向的那个节点与头结点相连,然后删掉tail指向的尾节点,实现尾删。

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

9)查找函数实现。😊

代码实现思路详解:

//9)查找函数,先assert断言确保传入指针有效性,定义一个cur指向首节点,然后利用while遍历链表,找到的话就返回指针。找不到则返回空。

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

10)pos位置之前插入x的函数实现。😊

代码实现思路详解:

// 10)pos位置之前插入x。定义一个prev指针指向pos指向的前一个节点,然后新生成一个节点,通过指针相连方式将新生成的节点放到pos与prev的中间。

void ListInsert(ListNode* pos, LTDataType x)
{assert(pos);ListNode* prev = pos->prev;ListNode* newnode = BuyListNode(x);// prev newnode posprev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}

11)删除pos位置的值的函数实现。😊

代码实现思路详解:

// 11)删除pos位置的值。定义一个prev指针指向pos前一个节点,定义一个next指向pos后一个节点,然后让这两个节点相连,删掉pos指向的节点。

void ListErase(ListNode* pos)
{assert(pos);ListNode* prev = pos->prev;ListNode* next = pos->next;prev->next = next;next->prev = prev;free(pos);
}

12)逆序输出的函数实现。😊

代码实现思路详解:

//12)逆序输出函数实现。定义一个phead指针指向尾节点,从后往前遍历链表,直到cur走到头结点为止。

void ListPrintBack(ListNode* phead)
{assert(phead);ListNode* cur = phead->prev;while (cur != phead){printf("%d ", cur->data);cur = cur->prev;}printf("\n");
}

13)判空函数实现。😊

代码实现思路详解:

//13)判空函数实现,只要phead的前指针指向自己,则认为这链表为空链表。

bool ListEmpty(ListNode* phead)
{assert(phead);if (phead->prev == phead){return 1;}return -1;

3.测试文件源码分享:🙌


#include "SlistNode.h"void TestList1()
{//创建带头节点的空双向链表ListNode* plist = ListInit();//判空int ret = ListEmpty(plist);if (ret == 1){printf("链表为空\n");}else{printf("链表不为空\n");}//尾插1,2,3,4,5ListPushBack(plist, 1);ListPushBack(plist, 2);ListPushBack(plist, 3);ListPushBack(plist, 4);ListPushBack(plist, 5);ListPrintFront(plist);//头插0,-1ListPushFront(plist, 0);ListPushFront(plist, -1);ListPrintFront(plist);//头删三个数据ListPopFront(plist);ListPopFront(plist);ListPopFront(plist);ListPrintFront(plist);//尾删一个数据ListPopBack(plist);ListPrintFront(plist);//判空int ret1 = ListEmpty(plist);if (ret1 == 1){printf("链表不为空\n");}else{printf("链表为空\n");}// 查找,附带着修改的作用ListNode* pos = ListFind(plist, 3);if (pos){pos->data *= 10;printf("找到了,并且节点的值乘以10\n");}else{printf("没有找到\n");}ListPrintFront(plist);//在pos前插入一个300ListInsert(pos, 300);ListPrintFront(plist);//删除pos位置的节点ListErase(pos);//顺序输出链表数据ListPrintFront(plist);//逆序输出链表数据ListPrintBack(plist);
//删除链表ListDestory(plist);}int main()
{TestList1();return 0;
}

程序功能测试结果图:
在这里插入图片描述

总结撒花💞

   本篇文章旨在分享详解C语言动态实现带头结点的双向循环链表结构。希望大家通过阅读此文有所收获实现带头结点的双向循环链表结构,相比于单链表结构更加复杂一点,它的成员相比单链表多了一个指针。本次实现难点在于对指针的运用和对多种情况的考虑。在实现前一定要通过画图的方式将思路和需要注意的情况想清楚然后再来尝试用代码进行实现。基本实现出双链表后可以思考能不能优化代码的问题。
   😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘

http://www.hkea.cn/news/480840/

相关文章:

  • 免费的网站给一个百度seo优化服务项目
  • 现代广告创意设计郑州百度网站优化排名
  • 兰州网站建设哪家专业谷歌seo网站推广
  • 崇信门户网站留言回复上优化seo
  • 网站建设费用有哪些站长工具搜索
  • 云主机能干什么独立站seo怎么做
  • 苏州专业网站建设设计公司免费发布推广信息的b2b
  • 空间 两个网站网络推广培训班
  • 零基础学做网站推广公司简介
  • 公司做网站最好引擎搜索器
  • 济南手工网站建设北京百度seo服务
  • 网站建设原创百度seo官网
  • 徐州企业网站建设衡阳seo服务
  • 网站自然排名优化seo专员是什么职业
  • 视频网站制作广告代理公司
  • wordpress主题域名授权密钥生成镇海seo关键词优化费用
  • 北京东直门+网站建设汕头seo外包平台
  • 长沙 做网站企业网络组网设计
  • 北京哪家做网站优化产品seo基础优化
  • 招商加盟网站建设百度网址安全检测
  • 知名做网站费用2024年将爆发新瘟疫
  • 河北省城乡与建设厅网站企业关键词排名优化哪家好
  • 网站开发合同协议百度百科推广费用
  • 推荐黄的网站产品推广策划
  • 济南网站建设设计公司线上运营推广
  • 小清新 wordpressseo排名是什么意思
  • 从客户—管理者为某一公司做一份电子商务网站管理与维护的方案自媒体是如何赚钱的
  • 黑龙江住房和城乡建设厅网站首页每日精选12条新闻
  • 做网站工作都包括什么企业网站搭建
  • 自己可以进行网站建设吗河北网站推广