小工具知识网

当前位置: 首页 > 行业知识 > [数据结构] 双向带头链表的学习

行业知识

[数据结构] 双向带头链表的学习

2026-11-05 10:00:26 来源:互联网转载

一.带头,双向

1.带头可能对初���者来说是一种优势,因为有了头(哨兵位),不需要运用二级指针,因为第一的位置已经确定,(二级指针用在不带头的修改头的值), 相对来说可能更加好理解,但是带头,这个头哨兵位存储的数据却没有很大的意义,实践意义并不大.

()

2.双向的链表,有一个好处,解决了单链表不能够找到前一个的问题,链表之间形成了循环,数据的修改更加便捷,当然相对而言也是更加复杂的.

二.带头双向链表的实现

头文件
#pragma once#include#include​​// 带头+双向+循环链表增删查改实现typedef int LTDataType;​typedef struct ListNode{    LTDataType data;    struct ListNode* next;    struct ListNode* prev;}ListNode;​​// 创建返回链表的头结点.ListNode* ListInitate();​// 双向链表销毁void ListDestory(ListNode* pHead);​// 双向链表打印void ListPrint(ListNode* pHead);​// 双向链表尾插void ListPushBack(ListNode* pHead, LTDataType x);​// 双向链表尾删void ListPopBack(ListNode* pHead);​// 双向链表头插void ListPushFront(ListNode* pHead, LTDataType x);​// 双向链表头删void ListPopFront(ListNode* pHead);​// 双向链表查找ListNode* ListFind(ListNode* pHead, LTDataType x);​// 双向链表在pos的前面进行插入void ListInsert(ListNode* pos, LTDataType x);​// 双向链表删除pos位置的节点void ListErase(ListNode* pos);
主体部分的实现(realize.c)
#include"twohead.h"​//创建一个节点ListNode* CreateNode(LTDataType x){    ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));    if (newnode == NULL)    {        printf("malloc failed");        exit(-1);    }​    newnode->data = x;    newnode->next = NULL;    newnode->prev = NULL;        return newnode;​}​//链表的初始化ListNode* ListInitate(){    ListNode* phead = CreateNode(-1);    phead->next = phead;    phead->prev = phead;​    return phead;​}​//链表的打印void ListPrint(ListNode* pHead){    if (pHead == NULL)        return;    printf("哨兵位");​    ListNode* cur = pHead->next;    while (cur != pHead)    {        printf("%d", cur->data);        cur = cur->next;    }​}​//链表的销毁void ListDestory(ListNode* pHead){    free(pHead);    pHead = NULL;}​//链表的头插void ListPushFront(ListNode* pHead, LTDataType x){    if (pHead == NULL)        return;    ListNode* cur = CreateNode(x);    cur->next = pHead->next;    pHead->next = cur;    cur->prev = cur->next->prev;    cur->next->prev = cur;​}​//链表的头删void ListPopFront(ListNode* pHead){    if (pHead == NULL)        return;    if (pHead->next == pHead)        return;​    pHead->next = pHead->next->next;    pHead->next->prev->prev = pHead;​}​//链表的尾插void ListPushBack(ListNode* pHead, LTDataType x){    if (pHead == NULL)        return;    ListNode* cur = CreateNode(x);    ​    pHead->prev->next = cur;    cur->prev = pHead->prev;    cur->next = pHead;    pHead->prev = cur;​}​//链表的尾删void ListPopBack(ListNode* pHead){    if (pHead == NULL)        return;​    if (pHead->next == pHead)        return;        pHead->prev->prev->next = pHead;    pHead->prev = pHead->prev->prev;​}​//链表的查找ListNode* ListFind(ListNode* pHead, LTDataType x){    if (pHead == NULL)        return NULL;    if (pHead->next == pHead)        return NULL;    ListNode* cur = pHead->next;    while (cur!=pHead)    {        if (cur->data == x)            return cur;        cur = cur->next;    }​    return NULL;​}​//链表pos位置之前的插入void ListInsert(ListNode* pos, LTDataType x){    if (pos == NULL)        return;    ListNode* cur = CreateNode(x);    pos->prev->next = cur;    cur->next = pos;    cur->prev = pos->prev->next;    pos->prev = cur;}​//链表pos位置的删除void ListErase(ListNode* pos){    if (pos == NULL)        return;​    pos->prev->next = pos->next;    pos->next->prev = pos->prev;​}
测试样例的是实现
#include"twohead.h"​void test1(){    ListNode* head = ListInitate();    ListPushFront(head, 1);    ListPushFront(head, 2);    ListPushFront(head, 3);    ListPushFront(head, 4);    ListPushFront(head, 5);    ListPushFront(head, 6);    ListPrint(head);​    ListDestory(head);​}​void test2(){    ListNode* head = ListInitate();    ListPushFront(head, 1);    ListPushFront(head, 2);    ListPushFront(head, 3);    ListPushFront(head, 4);    ListPushFront(head, 5);    ListPushFront(head, 6);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);    ListPopFront(head);​    ListPrint(head);        ListDestory(head);​}​void test3(){    ListNode* head = ListInitate();    ListPushBack(head, 1);    ListPushBack(head, 2);    ListPushBack(head, 3);    ListPushBack(head, 4);    ListPushBack(head, 5);    ListPushBack(head, 6);​​​    ListPrint(head);    ListDestory(head);​}​void test4(){    ListNode* head = ListInitate();    ListPushBack(head, 1);    ListPushBack(head, 2);    ListPushBack(head, 3);    ListPushBack(head, 4);    ListPushBack(head, 5);    ListPushBack(head, 6);     ListPopBack(head);     ListPopBack(head);     ListPopBack(head);     ListPopBack(head);​​​​    ListPrint(head);    ListDestory(head);​}​void test5(){    ListNode* head = ListInitate();    ListPushBack(head, 1);    ListPushBack(head, 2);    ListPushBack(head, 3);    ListPushBack(head, 4);    ListPushBack(head, 5);    ListPushBack(head, 6);    ListPrint(head);    printf("\n");​    ListNode*cur= ListFind(head, 102);    printf("%p", cur);    ListDestory(head);​}​void test6(){    ListNode* head = ListInitate();    ListPushBack(head, 1);    ListPushBack(head, 2);    ListPushBack(head, 3);    ListPushBack(head, 4);    ListPushBack(head, 5);    ListPushBack(head, 6);    ListPrint(head);    printf("\n");​    ListNode* cur = ListFind(head, 4);    ListInsert(cur, 100);    ListPrint(head);    ListDestory(head);​}​void test7(){    ListNode* head = ListInitate();    ListPushBack(head, 1);    ListPushBack(head, 2);    ListPushBack(head, 3);    ListPushBack(head, 4);    ListPushBack(head, 5);    ListPushBack(head, 6);    ListPrint(head);    printf("\n");​    ListNode* cur = ListFind(head, 4);    ListErase(cur);    ListPrint(head);    ListDestory(head);​}​int main(){    //test1();    //test2();    //test3();    //test4();    //test5();    //test6();    //test7();​    return 0;​}

到此为止链表顺序表的所有内容讲解均完成.

()

上一篇:宝塔面板主题轻松切换秘籍,一键搞定,打造个性化界面!

下一篇:根域名服务器怎么开通?