阿米纳网站建设,自驾黄山旅游攻略,wordpress比较,自己怎么做网站视频赚钱文章目录 一.头结点二.双链表1双链表的概念与结构2.与单链表相比 三.循环链表1.关于循环链表2.循环链表的优点 四.带头双向循环链表1.带头双向循环链表2.结构图3.实现 五.代码一览 一.头结点
在链表中设置头结点的作用是什么 标识链表:头结点是链表的特殊节点,它的存在能够明确… 文章目录 一.头结点二.双链表1·双链表的概念与结构2.与单链表相比 三.循环链表1.关于循环链表2.循环链表的优点 四.带头双向循环链表1.带头双向循环链表2.结构图3.实现 五.代码一览 一.头结点
在链表中设置头结点的作用是什么 标识链表:头结点是链表的特殊节点,它的存在能够明确标识出这是一个链表。在链表中,头结点通常不包含任何数据,它的主要作用是作为链表的入口,使得链表的操作更加方便。 简化操作:头结点的存在可以简化链表的操作。例如,当我们需要遍历整个链表时,只需要从头结点开始即可,无需关心链表的起始位置。同时,头结点的存在也使得在链表末尾插入或删除节点等操作更加方便。 提高效率:头结点的存在可以提高链表操作的效率。由于头结点是链表的第一个节点,因此在遍历链表时,我们无需担心指针的移动方向问题。同时,由于头结点在链表中的特殊位置,当需要访问链表的第一个元素时,可以通过直接访问头结点来获取,无需遍历整个链表。 二.双链表
1·双链表的概念与结构 概念双链表是一种物理存储结构上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针双向链接次序实现的。 结构图
2.与单链表相比 双向性:双链表支持在每个节点上存储前驱节点和后继节点的指针,使得在任何节点上都可以方便地找到其前驱节点和后继节点。而单链表只能通过遍历整个链表来查找特定节点的下一个节点或上一个节点,效率较低。 插入和删除操作更高效:由于双链表支持双向链接,因此在插入和删除操作中,双链表只需要重新调整相关的指针即可,而不需要像单链表那样需要遍历整个链表。这使得双链表的插入和删除操作更高效。 三.循环链表
1.关于循环链表 循环链表是一种特殊的链表其中最后一个节点指向第一个节点即起始节点。起始节点充当列表开头的参考点。 1遍历时可以从任何节点开始并以任何方向向前或向后遍历列表直到到达开始的同一节点。 2循环链表没有开始也没有结束。 3在循环链表中最后一个节点地址部分保存第一个节点的地址从而形成一个循环链状结构。 4.结构图
2.循环链表的优点 1内存利用率是循环链表的共同优势之一 与线性数据结构不同循环链表可以让人有效地使用内存因为链表的大小动态增加或减少因此不会浪费内存。此外无需预先分配内存。 2实施 由于能够利用内存和易于数据操作像堆栈和队列这样的线性数据结构通常可以使用链表轻松实现。 3易于数据操作 可以有效地处理循环链表的插入和删除而无需重新构造链表。插入或删除元素后无需移动元素只需更新下一个指针中存在的地址。 四.带头双向循环链表
1.带头双向循环链表 结构最复杂一般用在单独存储数据。实际中使用的链表数据结构都是带头双向循环链表。另外这个结构虽然结构复杂但是使用代码实现以后会发现结构会带来很多优势实现反而简单了后面我们代码实现了就知道了。 2.结构图 3.实现
思路 1利用结构体存储数据和指针结构体能够存储不同类型的数据 2通过malloc函数进行扩容 3通过多条件实现 4我们实现初始化、打印、扩容、尾插、头插等函数 框架 结构体的创建、一些定义等 List.h
#includestdio.h
#includeassert.h
#includestdlib.h
typedef int LTDataType;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}ListNode;Test.c
void Test() {ListNode* plist ListInit()初始化头结点不存储数据;}
int main() {Test();return 0;
}函数实现 1扩容函数 返回值一个结构体指针 参数传来的数据 通过malloc函数实现扩容并将扩容后的指针置空和存储传来的数据 代码
ListNode* BuyListNode(LTDataType x) {//扩容ListNode* newnode (ListNode*)malloc(sizeof(ListNode));//扩容newnode-data x;//存储数据newnode-next NULL;//指针置空newnode-prev NULL;return newnode;//返回指针
}2初始化函数 我们开始要初始化一个头结点不存储数据 返回一个指针我们的头结点 代码
ListNode* ListInit() {//初始化ListNode* phead BuyListNode(0);//第一个数据不打印phead-next phead;//只有一个头结点因为是双向循环链表自己连接自己phead-prev phead;return phead;
}如图 打印函数 代码
void ListPrint(ListNode* phead) {assert(phead);//判断是否为空//初始条件ListNode* cat phead-next;//打印出头结点next指向的结构体开始//结束条件while (cat! phead)//当打印完一次后就会遇上同结点此时结束打印{printf(%d , cat-data);//迭代条件cat cat-next;}printf(\n);
}3尾插函数 我们要将一个数据尾插进去 第一步找到这个链表的结尾处我们可以通过头结点找到 第二步我们重新将结尾处结构体的next指向尾插进来的结构体再将尾插进来的结构体的prev指向结尾处的结构体再再将尾插进来的结构体的next指向头结点再再再将头结点的perv指向尾插进来的结构体 插前 插后 代码
void ListPushBack(ListNode* phead, LTDataType x) {//尾插assert(phead);//判断是否为空ListNode* newnode BuyListNode(x);//扩容ListNode* cat phead-prev;//找到尾结点并保存//重新连接cat-next newnode;newnode-prev cat;phead-prev newnode;newnode-next phead;
}检查 尾插 1 、2 、3
ListNode* plist ListInit();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);运行结果 4头插函数 我们要将一个数据尾插进去 第一步通过头结点找到第一个存储数据的点 第二步我们重新将第一存储数据的结点处结构体的prev指向头插进来的结构体再将头插进来的结构体的next指向第一个存储数据的结构体再再将头插进来的结构体的prtv指向头结点再再再将头结点的next指向头插进来的结构体
插前 插后 代码
void ListPushFront(ListNode* phead, LTDataType x) {//头插assert(phead);ListNode* newnode BuyListNode(x);ListNode* cat phead-next;//找到头结点并保存//重新连接cat-prev newnode;newnode-next cat;phead-next newnode;newnode-prev phead;
}检查
头插 0
ListNode* plist ListInit();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushFront(plist, 0);运行结果 5头删函数 我们想要删除第一个数据 第一步通过头结点找到第一个存储数据的结点再通过第一个存储数据的结点来找到第二个存储数据的结点 第二步将第一个存储数据的结点释放掉然后再将第二个存储数据的结点的prev指向头结点再再头结点的next指向第二个存储数据的结点 删前 删后
代码
void ListPopFront(ListNode* phead) {//头删assert(phead);assert(phead-next ! phead);//ListNode* cat phead-next-next;//通过第一个存储结点找到第二个存储的结点并保存free(phead-next);//释放掉phead-next NULL;//并置空//重新连接cat-prev phead;phead-next cat;}检查 头删一个数据
ListNode* plist ListInit();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushFront(plist, 0);
ListPopFront(plist);运行结果 6尾删函数 我们将最后一个结点删除 第一步通过头结点来找到最后一个结点再通过最后一个结点来找到倒数第二个结点 第二步将最后一个结点释放掉再将倒数第二个结点的next指向头结点再再将头结点的prev指向倒数第二个结点 删前 删后 检查 尾删一个数据
ListNode* plist ListInit();
ListPushBack(plist, 1);
ListPushBack(plist, 2);
ListPushBack(plist, 3);
ListPushFront(plist, 0);
ListPopFront(plist);
ListPopBack(plist);
ListPrint(plist);运行结果
五.代码一览
List.h
#define _CRT_SECURE_NO_WARNINGS
#includestdio.h
#includeassert.h
#includestdlib.h
typedef int LTDataType;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}ListNode;ListNode* ListInit();//初始化
void ListDestory(ListNode* phead);//清空
void ListPrint(ListNode* phead);//打印void ListPushBack(ListNode* phead, LTDataType x);//尾插
void ListPushFront(ListNode* phead, LTDataType x);//头插
void ListPopFront(ListNode* phead);//头删
void ListPopBack(ListNode* phead);//尾删List.c
#define _CRT_SECURE_NO_WARNINGS
#includeList.hListNode* BuyListNode(LTDataType x) {//扩容ListNode* newnode (ListNode*)malloc(sizeof(ListNode));newnode-data x;newnode-next NULL;newnode-prev NULL;return newnode;
}ListNode* ListInit() {//初始化ListNode* phead BuyListNode(0);phead-next phead;phead-prev phead;return phead;
}void ListPrint(ListNode* phead) {assert(phead);//初始条件ListNode* cat phead-next;//结束条件while (cat! phead){printf(%d , cat-data);//迭代条件cat cat-next;}printf(\n);
}
void ListPushBack(ListNode* phead, LTDataType x) {//尾插assert(phead);ListNode* newnode BuyListNode(x);ListNode* cat phead-prev;cat-next newnode;newnode-prev cat;phead-prev newnode;newnode-next phead;
}
void ListPushFront(ListNode* phead, LTDataType x) {//头插assert(phead);ListNode* newnode BuyListNode(x);ListNode* cat phead-next;cat-prev newnode;newnode-next cat;phead-next newnode;newnode-prev phead;
}
void ListPopFront(ListNode* phead) {//头删assert(phead);assert(phead-next ! phead);ListNode* cat phead-next-next;free(phead-next);phead-next NULL;cat-prev phead;phead-next cat;}
void ListPopBack(ListNode* phead) {//尾删assert(phead);assert(phead-prev ! phead);ListNode* cat phead-prev-prev;free(phead-prev);phead-prev NULL;cat-next phead;phead-prev cat;
}Test.c
void Test() {ListNode* plist ListInit();ListPushBack(plist, 1);ListPushBack(plist, 2);ListPushBack(plist, 3);ListPushFront(plist, 0);ListPopFront(plist);ListPopBack(plist);ListPrint(plist);}int main() {Test();return 0;
}以上就是全部代码了 还有一些查改等接口函数没实现感兴趣的可以去试试
以上就是我的分享了如果有什么错误欢迎在评论区留言。 最后谢谢大家的观看