循环双链表

#include<iostream>
using namespace std;
struct LinkNode
{
   int value;
   LinkNode* next;
   LinkNode* pre;
};
LinkNode* createDoubleRoundLinkList()
{
    LinkNode* head = (LinkNode*)malloc(sizeof(LinkNode));
    head->next=head;
    head->pre=head;
    head->value=0;
    return head;
}

bool insertElem(int pos,int value,LinkNode* head)
{
    if(pos<=0)return 0;

    LinkNode* p = head;
    int j=0;
    while(p->next!=head && j<pos-1)//任然定位到pos-1的元素,也就是待插入元素的位置前一个,其实书上写的是到POS位置,但这样不能插在末尾了
    {
         p=p->next;
         j++;
    }
    if(j==pos-1)
    {
        LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
        newNode->value=value;
        newNode->next=p->next;
        p->next=newNode;
        newNode->pre=p;
        if(newNode->next)//针对在链表末端的一个边界
            newNode->next->pre=newNode;
        head->value++;
        return 1;
    }
    return 0;
}
bool deleElem(int pos,LinkNode* head)
{
    if(pos<=0)return 0;
    LinkNode* p = head;
    int j=0;
    while(p->next!=head && j<pos)
    {
        p=p->next;
        j++;
    }
    if(j==pos)//这里可以定位到pos的元素,也就是待删除元素的位置,这里通过j==pos判断出合法情况,之所以不用p==head原因和循环单链表的一样
    {
        p->pre->next=p->next;
        p->next->pre=p->pre;//p->next不会为空
        delete(p);
        head->value--;
        return 1;
    }
    return 0;
}
void clearLinkList(LinkNode* head)
{
    LinkNode*p = head->next;
    while(p!=head)
    {
        LinkNode* q = p->next;
        deleElem(1,head);//每次删除第一个,逐个删除
        p=q;
    }
}

void destroyLinkList(LinkNode* head)
{
   clearLinkList(head);
   delete head;
   head = 0;
}

void outPut(LinkNode* head)
{
    if(head == NULL)
    {
       cout<<"link list dose not exist"<<endl;
       return;
    }
    if(head->value==0)
    {
        cout<<"link list is empty"<<endl;
        return;
    }
    LinkNode* p = head->next;
    while(p!=head)
    {
         cout<<p->value<<" ";
         p=p->next;
    }
    cout<<endl;
}

void main()
{
    int len=12;
    LinkNode* L= createDoubleRoundLinkList();
    int v;
    for(int i=0;i<len;i++)
    {
         v = rand() % 100;
         cout<<v<<" ";
         insertElem(1,v,L);//每次在链表尾部插入,使得输入的顺序和链表中的顺序相反
    }
    cout<<endl;
    outPut(L);
    destroyLinkList(L);
   //outPut(L);
    L= createDoubleRoundLinkList();
    for(int i=0;i<len;i++)
    {
         v = rand() % 100;
         cout<<v<<" ";
         insertElem(L->value+1,v,L);//每次在链表尾部插入,使得输入的顺序和链表中的顺序一致

    }
    cout<<endl;
    outPut(L);
    insertElem(3,999,L);
    outPut(L);
    insertElem(100,999,L);
    outPut(L);
    insertElem(L->value,9999,L);
    outPut(L);
    insertElem(L->value+1,8888,L);
    outPut(L);
    insertElem(1,7777,L);
    outPut(L);
    deleElem(1,L);
    outPut(L);
    deleElem(100,L);
    outPut(L);
    deleElem(7,L);
    outPut(L);
    deleElem(L->value,L);
    outPut(L);
    deleElem(L->value+1,L);
    outPut(L);
    clearLinkList(L);
    outPut(L);
    insertElem(1,2,L);
    outPut(L);
    deleElem(L->value,L);
    outPut(L);
    cin>>len;
}
时间: 2024-08-05 16:07:40

循环双链表的相关文章

循环双链表的简单实现

<span style="font-size:18px;"><strong>//代码为自己编写,可能有问题,欢迎大家留言指正!</strong></span> <span style="font-size:18px;"><strong> </strong></span> #include <iostream> #include <string> u

数据结构之自建算法库——循环双链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时循环链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:cdlinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CDLINKLIST_H_INCLUDED #define CDLINKLIST_H_INCLUDED //循环双链表基本运算函数 typedef int E

C语言实现非循环双链表节点的删除(不带头结点)

不带头结点的非循环双链表在删除节点的时候比价麻烦,因为同时要维护prior和next两个指针.在处理第一个节点和最后一个节点的时候都要分别考虑,同时也需要考虑节点数量为1的情况.删除情况分为下面两类: (1)删除pos位置的节点: (2)判断x是否在链表中,若存在则删除: 代码上传至 https://github.com/chenyufeng1991/DeleteNodeDoubleList  . 核心代码如下: //删除pos位置的节点 Node *deletePosList(Node *pN

C语言实现非循环双链表节点的删除(带头结点尾结点)

我在之前一篇博客<C语言实现非循环双链表节点的删除(不带头结点)>中详细讲解了不含头尾节点的双链表中删除一个节点,处理过程还是稍显麻烦.自从我们学习使用头尾节点来处理双链表后,删除过程就非常方便.代码上传至 https://github.com/chenyufeng1991/DeleteNodeDoubleLinkedList_HeadList . 核心代码如下: //删除pos位置的节点 int DeletePosList(Node *pHead,Node *pTail,int pos){

C实现头插法和尾插法来构建非循环双链表(不带头结点)

在实际使用中,双链表比单链表方便很多,也更为灵活.对于不带头结点的非循环双链表的基本操作,我在<C语言实现双向非循环链表(不带头结点)的基本操作>这篇文章中有详细的实现.今天我们就要用两种不同的方式头插法和尾插法来建立双链表.代码上传至  https://github.com/chenyufeng1991/HeadInsertAndTailInsertDoubleList  . 核心代码如下: //尾插法创建不带头结点的非循环双向链表 Node *TailInsertCreateList(No

数据结构实践——循环双链表应用

本文针对数据结构基础系列网络课程(2):线性表的实践项目. [项目- 循环双链表应用] 设非空线性表ha和hb都用带头节点的循环双链表表示.设计一个算法Insert(ha,hb,i).其功能是:i=0时,将线性表hb插入到线性表ha的最前面:当i>0时,将线性表hb插入到线性表ha中第i个节点的后面:当i大于等于线性表ha的长度时,将线性表hb插入到线性表ha的最后面. 请在实现算法时,除项目中给出的特殊要求,其余工作均可利用项目4完成的算法支持. [参考解答](循环双链表的基本运算算法,请参考

Python与数据结构[0] -&gt; 链表[1] -&gt; 双链表与循环双链表的 Python 实现

双链表 / Doubly Linked List 目录 双链表 循环双链表 1 双链表 双链表和单链表的不同之处在于,双链表需要多增加一个域(C语言),即在Python中需要多增加一个属性,用于存储指向前一个结点的信息. Doubly linked list: node_1 <---> node_2 <---> node_3 完整代码 1 from linked_list import LinkedList, test 2 3 4 class NodeDual: 5 def __i

线性表之循环双链表

#include<iostream> using namespace std; struct LinkNode { int value; LinkNode* next; LinkNode* pre; }; LinkNode* createDoubleRoundLinkList() { LinkNode* head = (LinkNode*)malloc(sizeof(LinkNode)); head->next=head; head->pre=head; head->valu

循环双链表 | 判断链表元素是否对称

王道P39T17 主代码: bool symmetry(DLinkList& L){ DNode *p=L->next,*q=L->prior; while(p!=q && p->data==q->data){ p=p->next; q=q->prior; } if(p==q) return true; return false; } 完整代码: #include <cstdio> #include <stdlib.h>