个人网站建设的论文,网站建设心得8000字,环保部网站建设项目验收方案,wordpress网页慢循环链表#xff1a;循环单链表、循环双链表
1. 循环单链表 循环单链表#xff08;Circular Singly Linked List#xff09;是一种特殊类型的单链表#xff0c;其中最后一个节点的指针指向头节点#xff0c;形成一个循环。 循环单链表与普通单链表的主要区别在于#xf…循环链表循环单链表、循环双链表
1. 循环单链表 循环单链表Circular Singly Linked List是一种特殊类型的单链表其中最后一个节点的指针指向头节点形成一个循环。 循环单链表与普通单链表的主要区别在于循环单链表的尾节点的指针不是指向 nullptr而是指向头节点形成一个闭环。这意味着在循环单链表中可以通过尾节点的指针重新回到头节点。 循环单链表可以具有以下特点和优势 尾节点的指针指向头节点使得在遍历链表时不需要特别处理尾节点方便实现循环遍历。可以更容易地进行环形操作如判断链表是否形成环、寻找环的起始点等。循环单链表的插入和删除操作相对简单因为不需要特别处理头部和尾部情况。在使用循环单链表时我们需要额外关注以下几点在插入和删除节点时要确保更新指针的正确性以避免死循环或链表中断。在循环单链表中遍历时要设置终止条件防止进入无限循环。
1.1 初始化一个循环单链表
typedef struct LNode //定义单链表结合类型
{ElemType data; //每个结点存放一个一个数据元素struct LNode *next; //指针指向下一个结点
}LNode, *LinkList;//初始化一个循环单链表
bool InitList(LinkList L)
{L (LNode *) malloc(sizeof(LNode)); //分配一个头结点if(L NULL) //内存不足、分配失败return false;L-next L; //头结点next指向头结点return true;
}2.2 判断单链表是否为空
//判断循环单链表是否为空, 检查头结点指针是否指向它自己就行,如下图所示
bool Empty(LinkList L)
{if(L-next L) //检查头结点指针是否指向它自己return true;else return false;
}2.3 判断 p 结点是否为循环单链表的表尾结点
//判断 p 结点是否为循环单链表的表尾结点
bool isTail(LinkList L, LNode *p)
{if(p-next L)return true;elsereturn false;
}从头结点找到尾部时间复杂度为O(n), 从尾部找到头部时间复杂度为O(1), 可以让L指向表尾元素(插入、删除时可能需要修改L) 2. 循环双链表 循环双链表Circular Doubly Linked List是一种特殊类型的双向链表其中最后一个节点的下一个指针指向头节点头节点的前一个指针指向最后一个节点形成一个循环。 循环双链表与普通双链表的主要区别在于循环双链表既具有双向链表的前驱和后继关系也具有循环遍历的能力。 双链表表头结点的prior指向NULL; 表尾结点的next指向NULL。 循环双链表表头结点的prior指向表尾结点 表尾结点的next指向头结点。
2.1循环双链表的特点和优势
可以通过任意节点的前驱和后继指针方便地在双链表中进行插入和删除操作。最后一个节点的下一个指针指向头节点使得在遍历链表时不需要特别处理尾节点可以很方便地实现循环遍历。可以更容易地进行环形操作如判断链表是否形成环、寻找环的起始点等。循环双链表的插入和删除操作相对简单不需要特别处理头部和尾部情况。 在插入和删除节点时要确保更新前驱和后继指针的正确性以避免链表中断或形成其他错误结构。 在循环双链表中遍历时要设置终止条件防止进入无限循环。 2.2 循环双链表的初始化 当我们在初始化一个双链表时需要让头结点的前指针和后指针都指向头结点自己而普通的双链表指向NULL如下图所示 //初始化空的循环双链表
bool InitDLinkList(DlinkList L)
{L (DNode*) malloc(sizeof(DNode)); //分配一个头结点if(L NULL) //内存不足分配失败return false;L-prior L; //头结点的prior指向头结点L-next L; //头结点的next指向头结点return true; //初始化成功
}2.3 判断循环链表是否为空
typedef struct DNode //创建循环双链表
{ElemType data;struct DNode *prior,*next;
}DNode, *DLinkList;void testDLinkList()
{//初始化循环双链表DLinkList L;InitDLinkList(L);//.......后续代码.......
}
//判断循环链表是否为空
bool Empty(DLinkList L)
{if(L-next L)return true;elsereturn false;
}
2.4 判断结点p是否为循环双链表的表尾结点
bool isTail(DLinkList L, DNode *p)
{if(p-next L)return true;elsereturn false;
}2.5 双链表的插入
//在p结点之后插入s结点
bool InsertNextDNode(DNode *p, DNode *s)
{s-next p-next; //将结点*s插入到结点*p之后p-next-prior s; //如果s-prior p;p-next s;
}2.6 双链表的删除
//删除p的后继结点q
p-next q-next;
q-next-prior p; //如果p没有后继结点普通循环链表会出问题
free(q);3. 知识回顾