C++实现双向循环链表的详细步骤

需积分: 18 0 下载量 45 浏览量 更新于2024-08-05 收藏 4KB TXT 举报
"C++实现双向循环链表的代码示例" 在C++编程中,双向循环链表是一种数据结构,它允许我们在链表的任一节点处进行前向和后向的遍历。这个链表的每个节点都包含一个指向前一个节点和后一个节点的指针,而且链表的最后一个节点指向前一个即第一个节点,形成一个环形结构。这种设计使得在链表中插入和删除操作更为高效,因为可以从两个方向访问相邻的节点。 以下是一个使用C++实现双向循环链表的类`DClist`的代码示例: 首先,定义链表节点的结构体`Dnode`,包含数据成员`data`(用于存储数据),以及两个指针成员`pre`和`next`,分别指向前一个节点和后一个节点。 ```cpp typedef struct node { int data; node* pre; node* next; } Dnode, *Pdnode; ``` 接下来,定义一个名为`DClist`的类,包含私有成员变量`head`(链表头节点)和`size`(链表中的元素数量)。类的构造函数初始化链表,创建一个空的循环链表。析构函数负责清理链表,释放所有节点的内存。 ```cpp class DClist { private: Pdnode head; int size; public: DClist() { // 构造函数 cout << "DClist()" << endl; size = 0; head = (Dnode*)malloc(sizeof(Dnode)); if (NULL == head) { exit(1); } head->next = head; head->pre = head; } ~DClist() { // 析构函数 cout << "~DClist()" << endl; Clear(); FreeNode(head); } ``` `DClist`类提供了几个公共方法,如`GetSize()`返回链表的大小,`IsEmpty()`检查链表是否为空,`BuyNode()`分配一个新的节点,`FreeNode()`释放一个节点的内存。 ```cpp int GetSize() { return size; } bool IsEmpty() { return size == 0; } Dnode* BuyNode() { // 创建新节点 Pdnode p = (Dnode*)malloc(sizeof(Dnode)); if (NULL != p) { memset(p, 0, sizeof(Dnode)); } return p; } void FreeNode(Pdnode p) { free(p); p = NULL; } ``` 插入节点的方法`Insert_pre(Pdnode p, int val)`允许在指定节点`p`之前插入一个值为`val`的新节点。首先,创建新节点,然后更新新节点和相邻节点的指针关系,最后将链表大小加一。 ```cpp bool Insert_pre(Pdnode p, int val) { // 在节点p之前插入值为val的新节点 if (NULL == p) return false; Pdnode newnode = (Dnode*)malloc(sizeof(Dnode)); if (NULL == newnode) return false; newnode->data = val; // 初始化新节点的数据 newnode->pre = p->pre; // 新节点的前驱是原节点的前驱 newnode->next = p; // 新节点的后继是原节点 p->pre = newnode; // 原节点的前驱改为新节点 newnode->pre->next = newnode; // 原节点的前驱的后继改为新节点 size++; return true; } ``` 这个类没有展示删除节点、遍历链表等其他常见操作的实现,但根据双向循环链表的性质,这些操作可以类似地完成。例如,删除节点通常涉及找到待删除节点的前后节点,更新它们的指针,然后释放节点内存。遍历链表则可以通过当前节点的`next`指针来移动到下一个节点,直到回到链表的起点。 这个C++实现的双向循环链表类提供了一个基础框架,可以根据实际需求扩展更多的功能,如插入、删除、查找、排序等。双向循环链表在处理需要频繁在链表两端进行操作的问题时,相比于单链表有着更高的效率。