循环双链表的C++实现



    前面一篇文章里实现的是一般的非循环双链表(http://blog.csdn.net/wonggonghong/article/details/21605423)。而下面我们来实现一个循环双链表。

     

    循环双链表通过指针将头节点与尾节点也建立了与其他节点间相似的连接方式。这样做之后,就淡化了链表中存在表头与表尾的意义。因为事实上,链表中任意两个相邻节点之间的连接关系都是一样的。我们将循环双链表的数据结构表示成“圆圈”结构,如图(箭头均表示指针指向):

而一个单节点的循环双链表可以看成该节点自连接形成的“圆圈”结构,如下图所示:

       

即满足条件:Single_Lists->previous= Single_Lists->next = Single_Lists

    于是,对于循环双链表中的任意节点都可以同等看待,不存在特殊节点(头节点、尾节点)。我们基于前面的双链表结构,实现循环双链表。

    在<List.h>头文件里声明循环双链表结构:

#include "list.h"

//循环的双链表结构,包含一些常见的操作
#ifndef _List_H_
#define _List_H_

#include <iostream>

struct Double_Node{
	int element;  //节点存储信息可以根据需要修改!
	Double_Node* previous;
	Double_Node* next;
};

Double_Node* CreateLists(int X); //创建一个循环双链表(此时只有一个节点)
void OutputLists(Double_Node* Lists); //输出链表中所有元素的值
void DeleteLists(Double_Node* Lists); //删除循环双链表
Double_Node* Find(int X, Double_Node* Lists);   //从循环双链表中查找X
void Delete(int X, Double_Node* Lists);
void Insert(Double_Node* P, int X); //在节点P后面插入X
int GetNumofNodes(Double_Node* Lists); //返回节点总个数

#endif

       然后,在<List.cpp>文件里实现循环双链表操作(由于不存在特殊节点,部分操作可以简化):

#include "list.cpp"

#include "list.h"
#include <assert.h>

Double_Node* CreateLists(int X)
{
	Double_Node* Lists = new Double_Node;
	Lists->element = X;
	Lists->previous = Lists->next = Lists; //单节点链表形成自循环
	return Lists;
}

void DeleteLists(Double_Node* Lists)  
{
	assert(Lists);
	Double_Node* P = Lists->next, *temp;
	Lists->next = P->previous = NULL;
	while(P!=Lists)  
	{  
		temp = P->next; 
        P->next = temp->previous = NULL;					
		delete P;  
		P = temp;  
	}
	delete Lists;
}  

Double_Node* Find(int X, Double_Node* Lists)
{
	assert(Lists);
	Double_Node* P = Lists;
	do{
		if(P->element == X)
			return P;
		else
			P = P->next;
	}while(P!=Lists);
	return NULL;
}

void Delete(int X, Double_Node* Lists)
{
	Double_Node* temp = Find(X,Lists); //如果没找到X,则temp=NULL
	if(temp)
	{
		temp->previous->next = temp->next;
		temp->next->previous = temp->previous;
		temp->previous = temp->next = NULL;
		delete temp;
	}
}

void Insert(Double_Node* P, int X)
{
	assert(P);
	Double_Node* tempX = new Double_Node;
	tempX->element = X;
	tempX->previous = P;
	tempX->next = P->next;
	P->next->previous = tempX;	   
	P->next = tempX;
}

void OutputLists(Double_Node* Lists)
{
	assert(Lists);
	Double_Node* P = Lists;
	do{
		std::cout<<P->element<<"   ";
		P = P->next;
	}while(P!=Lists);
	std::cout<<std::endl;
}

int GetNumofNodes(Double_Node* Lists)
{
	assert(Lists);
	int count = 1;
	Double_Node* P = Lists->next;
	while(P!=Lists)
	{
         count++;
		 P = P->next;
	}
	return count;	
}
最后,同样用一段 main 代码验证一下:
#include <iostream>
#include "list.h"

using namespace std;

int main()
{
	int Data[10] = {1,3,4,6,0,2,5,8,12,13};
	Double_Node* Lists = CreateLists(1);
	Double_Node* P = Lists;
	for(int i=1;i<10;i++)
	{
		Insert(P,Data[i]);
		P = P->next;
	}
	cout<<"打印出循环双链表的所有元素:\n";
	OutputLists(Lists);
	if(Find(8,P))
		cout<<"Find函数没有问题!!\n";
	Delete(8,Lists);
	cout<<"Delete节点8后,再打印出(非循环)双链表的所有元素:\n";
	OutputLists(Lists);
	cout<<"循环双链表总节点数为:"<<GetNumofNodes(P)<<endl;
	DeleteLists(Lists);
	return 0;
}
结果如下:





 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言实现循环链表的完整代码: ``` #include <stdio.h> #include <stdlib.h> // 双循环链表结点的定义 typedef struct Node { int data; struct Node* prev; struct Node* next; } Node; // 双循环链表的定义 typedef struct DoubleLinkedList { Node* head; int size; } DoubleLinkedList; // 创建一个新结点 Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->prev = NULL; newNode->next = NULL; return newNode; } // 初始化双循环链表 void initDoubleLinkedList(DoubleLinkedList* list) { list->head = NULL; list->size = 0; } // 在双循环链表的末尾插入一个结点 void insertNodeAtEnd(DoubleLinkedList* list, int data) { Node* newNode = createNode(data); if (list->head == NULL) { list->head = newNode; newNode->prev = newNode; newNode->next = newNode; } else { Node* lastNode = list->head->prev; lastNode->next = newNode; newNode->prev = lastNode; newNode->next = list->head; list->head->prev = newNode; } list->size++; } // 在双循环链表的指定位置插入一个结点 void insertNodeAtIndex(DoubleLinkedList* list, int index, int data) { if (index < 0 || index > list->size) { printf("Invalid index!\n"); return; } if (index == 0) { insertNodeAtFront(list, data); return; } if (index == list->size) { insertNodeAtEnd(list, data); return; } Node* newNode = createNode(data); Node* curNode = list->head; for (int i = 0; i < index - 1; i++) { curNode = curNode->next; } newNode->prev = curNode; newNode->next = curNode->next; curNode->next->prev = newNode; curNode->next = newNode; list->size++; } // 在双循环链表的头部插入一个结点 void insertNodeAtFront(DoubleLinkedList* list, int data) { insertNodeAtIndex(list, 0, data); } // 在双循环链表的末尾删除一个结点 void deleteNodeAtEnd(DoubleLinkedList* list) { if (list->head == NULL) { printf("The list is empty!\n"); return; } if (list->size == 1) { free(list->head); list->head = NULL; } else { Node* lastNode = list->head->prev; lastNode->prev->next = list->head; list->head->prev = lastNode->prev; free(lastNode); } list->size--; } // 在双循环链表的指定位置删除一个结点 void deleteNodeAtIndex(DoubleLinkedList* list, int index) { if (index < 0 || index >= list->size) { printf("Invalid index!\n"); return; } if (index == 0) { deleteNodeAtFront(list); return; } if (index == list->size - 1) { deleteNodeAtEnd(list); return; } Node* curNode = list->head; for (int i = 0; i < index; i++) { curNode = curNode->next; } curNode->prev->next = curNode->next; curNode->next->prev = curNode->prev; free(curNode); list->size--; } // 在双循环链表的头部删除一个结点 void deleteNodeAtFront(DoubleLinkedList* list) { deleteNodeAtIndex(list, 0); } // 打印双循环链表 void printDoubleLinkedList(DoubleLinkedList* list) { if (list->head == NULL) { printf("The list is empty!\n"); return; } Node* curNode = list->head; for (int i = 0; i < list->size; i++) { printf("%d ", curNode->data); curNode = curNode->next; } printf("\n"); } int main() { DoubleLinkedList list; initDoubleLinkedList(&list); insertNodeAtEnd(&list, 1); insertNodeAtEnd(&list, 2); insertNodeAtEnd(&list, 3); insertNodeAtFront(&list, 0); insertNodeAtIndex(&list, 3, 4); printDoubleLinkedList(&list); deleteNodeAtEnd(&list); deleteNodeAtIndex(&list, 2); deleteNodeAtFront(&list); printDoubleLinkedList(&list); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值