双向循环链表只找头节点的下一个的遍历代码
时间: 2024-10-18 09:25:00 浏览: 22
双向循环链表是一种特殊的链表结构,在这种链表中,每个节点除了包含指向下一个节点的指针外,还包含一个指向前一个节点的指针。如果你只需要从头节点开始按照单向顺序遍历,找到头节点的下一个节点,其代码会相对简单。这里是一个基本的伪代码示例:
```python
// 假设你有一个名为ListNode的节点类,有两个属性next(指向下一个节点)和prev(指向前一个节点)
ListNode* current = head; // 初始时current指向头节点
while (current != NULL) { // 当current不为空时继续遍历
// 这里你可以访问当前节点的数据
doSomethingWithNode(current);
// 移动到下一个节点
current = current->next;
// 如果到达链表尾部,current会变为NULL,此时prev应该为NULL,我们通常需要检查一下
if (current == NULL && prev != NULL) {
// 如果prev不为NULL,说明我们回到了起点,这时可以跳出循环
break;
}
}
```
注意,这个例子假设了循环链表的特性,即最后一个节点的`next`是指向头节点的,而`head`的`prev`通常设置为`NULL`。
相关问题
用C++实现一个基于模板的双向循环链表并且每个节点可以衍生出一条双向循环链表并加上详细的注释
下面是基于模板的双向循环链表的实现,每个节点可以衍生出一条双向循环链表,并加上详细的注释。
```c++
#include <iostream>
using namespace std;
// 定义双向循环链表节点
template<typename T>
struct ListNode{
T data; // 数据域
ListNode<T>* prev; // 前驱指针
ListNode<T>* next; // 后继指针
ListNode<T>* sublist; // 子列表指针
};
// 双向循环链表类
template<typename T>
class DoublyLinkedList{
private:
ListNode<T>* head; // 头指针
int length; // 链表长度
public:
// 构造函数
DoublyLinkedList(){
head = new ListNode<T>; // 创建一个头节点
head->prev = head; // 头节点的前驱指向自己
head->next = head; // 头节点的后继指向自己
head->sublist = nullptr; // 头节点的子列表指向空
length = 0; // 链表长度初始化为0
}
// 析构函数
~DoublyLinkedList(){
ListNode<T>* p = head;
ListNode<T>* q = nullptr;
while(p != nullptr){ // 循环删除每个节点
q = p->next;
delete p;
p = q;
}
head = nullptr;
length = 0;
}
// 获取链表长度
int getLength(){
return length;
}
// 在链表末尾添加一个节点
void addNode(T data){
ListNode<T>* p = head->prev; // 找到尾节点
ListNode<T>* q = new ListNode<T>; // 创建新节点
q->data = data; // 初始化新节点数据
q->prev = p; // 新节点的前驱指向尾节点
q->next = head; // 新节点的后继指向头节点
q->sublist = nullptr; // 新节点的子列表指向空
p->next = q; // 尾节点的后继指向新节点
head->prev = q; // 头节点的前驱指向新节点
length++; // 链表长度加1
}
// 删除链表中第一个值为data的节点
bool deleteNode(T data){
ListNode<T>* p = head->next; // 从头节点开始遍历
while(p != head){
if(p->data == data){ // 找到要删除的节点
p->prev->next = p->next; // 修改前驱节点的后继指向
p->next->prev = p->prev; // 修改后继节点的前驱指向
delete p; // 释放节点内存
length--; // 链表长度减1
return true;
}
p = p->next; // 继续向后遍历
}
return false; // 没有找到要删除的节点
}
// 在链表中查找第一个值为data的节点
ListNode<T>* findNode(T data){
ListNode<T>* p = head->next; // 从头节点开始遍历
while(p != head){
if(p->data == data){ // 找到要查找的节点
return p;
}
p = p->next; // 继续向后遍历
}
return nullptr; // 没有找到要查找的节点
}
// 在节点p处插入一个值为data的节点
bool insertNode(ListNode<T>* p, T data){
if(p == nullptr){ // 插入位置非法
return false;
}
ListNode<T>* q = new ListNode<T>; // 创建新节点
q->data = data; // 初始化新节点数据
q->prev = p->prev; // 新节点的前驱指向p的前驱
q->next = p; // 新节点的后继指向p
q->sublist = nullptr; // 新节点的子列表指向空
p->prev->next = q; // p的前驱节点的后继指向新节点
p->prev = q; // p的前驱指向新节点
length++; // 链表长度加1
return true;
}
// 衍生出一个新的双向循环链表
DoublyLinkedList<T>* derivative(ListNode<T>* p){
DoublyLinkedList<T>* sublist = new DoublyLinkedList<T>; // 创建新的双向循环链表
if(p != nullptr && p->sublist == nullptr){ // p节点存在且没有子列表
p->sublist = sublist->head; // 在p节点处记录子列表
return sublist; // 返回新的双向循环链表
}
return nullptr; // 衍生失败
}
// 打印链表中所有节点的数据
void printList(){
ListNode<T>* p = head->next; // 从头节点开始遍历
while(p != head){
cout << p->data << " ";
p = p->next; // 继续向后遍历
}
cout << endl;
}
// 打印节点p的子列表中所有节点的数据
void printSublist(ListNode<T>* p){
if(p != nullptr && p->sublist != nullptr){ // p节点存在且有子列表
DoublyLinkedList<T>* sublist = (DoublyLinkedList<T>*)(p->sublist); // 获取子列表的指针
sublist->printList(); // 打印子列表中所有节点的数据
}
}
};
int main(){
// 创建双向循环链表
DoublyLinkedList<int> list;
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(4);
list.addNode(5);
// 打印链表中所有节点的数据
cout << "list: ";
list.printList();
// 在链表中查找第一个值为3的节点
ListNode<int>* p = list.findNode(3);
if(p != nullptr){
// 在节点p处插入一个值为6的节点
list.insertNode(p, 6);
// 打印链表中所有节点的数据
cout << "list after insert: ";
list.printList();
}
// 在节点p处衍生出一个新的双向循环链表
DoublyLinkedList<int>* sublist = list.derivative(p);
if(sublist != nullptr){
// 在子列表中添加节点
sublist->addNode(7);
sublist->addNode(8);
// 打印链表中所有节点的数据
cout << "list with sublist: ";
list.printList();
// 打印节点p的子列表中所有节点的数据
cout << "sublist of p: ";
list.printSublist(p);
}
// 删除链表中第一个值为4的节点
list.deleteNode(4);
// 打印链表中所有节点的数据
cout << "list after delete: ";
list.printList();
return 0;
}
```
注:上述代码中的衍生操作可以用指针实现,不需要使用额外的空间来记录子列表。
用C++实现一个基于模板的双向循环链表并且每个节点可以衍生出一条单项双向链表并加上详细的注释
以下是基于模板的双向循环链表和每个节点可以衍生出一条单项双向链表的C++实现,注释已经加上:
```c++
#include <iostream>
using namespace std;
template <typename T> // 模板类
class DoubleLinkedList{
// 双向循环链表节点类
class Node{
friend class DoubleLinkedList; // 友元类,可以访问私有成员
friend class SingleLinkedList; // 友元类,可以访问私有成员
private:
T data; // 数据域
Node *pre; // 指向前驱节点的指针
Node *next; // 指向后继节点的指针
Node *listNext; // 指向单项双向链表的下一个节点
public:
Node(T value):data(value), pre(NULL), next(NULL), listNext(NULL){} // 构造函数
};
private:
Node *head; // 头指针
public:
DoubleLinkedList():head(NULL){} // 构造函数
// 插入节点
void insertNode(T value){
Node *newNode = new Node(value);
if(head == NULL){ // 链表为空
newNode->pre = newNode;
newNode->next = newNode;
head = newNode;
}
else{ // 链表不为空
newNode->next = head;
newNode->pre = head->pre;
head->pre->next = newNode;
head->pre = newNode;
}
}
// 删除节点
void deleteNode(T value){
if(head == NULL){ // 链表为空
cout<<"List is empty!"<<endl;
return;
}
Node *p = head;
while(p->data != value && p->next != head)
p = p->next;
if(p->data != value){ // 没有找到该节点
cout<<"Node not found!"<<endl;
return;
}
if(p == head && p->next == head){ // 链表只有一个节点
head = NULL;
}
else if(p == head){ // 要删除的节点为头节点
head->next->pre = head->pre;
head->pre->next = head->next;
head = head->next;
}
else{ // 要删除的节点不为头节点
p->next->pre = p->pre;
p->pre->next = p->next;
}
delete p;
p = NULL;
}
// 判断链表是否为空
bool isEmpty(){
return head == NULL;
}
// 打印链表
void printList(){
if(head == NULL){ // 链表为空
cout<<"List is empty!"<<endl;
return;
}
Node *p = head;
do{
cout<<p->data<<" ";
p = p->next;
}while(p != head);
cout<<endl;
}
// 衍生单项双向链表
void makeSingleLinkedList(){
if(head == NULL){ // 链表为空
cout<<"List is empty!"<<endl;
return;
}
Node *p = head;
do{
p->listNext = p->next;
p = p->next;
}while(p != head);
}
// 单项双向链表遍历
void traverseSingleLinkedList(){
if(head == NULL){ // 链表为空
cout<<"List is empty!"<<endl;
return;
}
Node *p = head;
do{
cout<<p->data<<" ";
p = p->listNext;
}while(p != head->next);
cout<<endl;
}
};
int main(){
DoubleLinkedList<int> dList; // 创建双向循环链表
// 插入节点
dList.insertNode(1);
dList.insertNode(2);
dList.insertNode(3);
dList.insertNode(4);
dList.insertNode(5);
// 打印链表
cout<<"Double Linked List: "<<endl;
dList.printList();
// 衍生单项双向链表
dList.makeSingleLinkedList();
// 单项双向链表遍历
cout<<"Single Linked List: "<<endl;
dList.traverseSingleLinkedList();
// 删除节点
dList.deleteNode(3);
dList.deleteNode(1);
// 打印链表
cout<<"Double Linked List: "<<endl;
dList.printList();
// 衍生单项双向链表
dList.makeSingleLinkedList();
// 单项双向链表遍历
cout<<"Single Linked List: "<<endl;
dList.traverseSingleLinkedList();
return 0;
}
```
以上代码可以实现基于模板的双向循环链表,每个节点可以衍生出一条单项双向链表,并且每段代码都有详细的注释,可以帮助理解。
阅读全文