带头双向循环链表 ~ 程序实现二
本篇博客基于 温故而知新 -> 数据结构 -> 线性表 -> 链表 中的理论知识,并利用 C++
中的 类 对数据结构中的 带头双向循环链表 进行代码实现!
其中涉及了链表的 增(头插、尾插、任插)删(头删、尾删、任删)查(节点寻找)改(没写(~ ̄▽ ̄)~),销毁,打印等操作!并附带了实例以及对应的运行结果!
具体内容如下:
(1)DList.h
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
typedef int DLTDataType;
// 双向节点
typedef struct DLTNode
{
DLTDataType _val;
struct DLTNode *_prev;
DLTNode *_next;
};
DLTNode *createNode(DLTDataType val)
{
DLTNode *node = (DLTNode*)malloc(sizeof(DLTNode));
node->_next = node->_prev = NULL;
node->_val = val;
return node;
}
// 双向链表
class DList
{
public:
DList()
{
_head = (DLTNode*)malloc(sizeof(DLTNode));
_head->_next = _head->_prev = _head;
}
~DList()
{
if(_head != NULL)
{
free(_head);
_head = NULL;
}
}
// 双向链表打印
void Print();
// 单节点打印
void NodePrint(DLTNode *node);
// 双向链表尾插
void PushBack(DLTDataType val);
// 双向链表尾删
void PopBack();
// 双向链表头插
void PushFront(DLTDataType val);
// 双向链表头删
void PopFront();
// 双向链表查找
DLTNode* Find(DLTDataType val);
// 双向链表在pos的前面进行插入
void Insert(DLTNode* pos, DLTDataType val);
// 双向链表删除pos位置的节点
void Erase(DLTNode* pos);
// 双向链表销毁
void Destory();
private:
DLTNode *_head;
};
(2)main.c
#include"DList.h"
// 双向链表打印
void DList::Print()
{
assert(_head->_next != _head);
DLTNode *cur = _head->_next;
cout << "链表内容:";
while (cur != _head)
{
cout << cur->_val << " ";
cur = cur->_next;
}cout << endl;
}
// 单节点打印
void DList::NodePrint(DLTNode *node)
{
cout << "该节点数据为:" << node->_val << endl;
}
// 双向链表尾插
void DList::PushBack(DLTDataType val)
{
DLTNode *newNode = createNode(val);
/* 方法一:正向找出最后一个节点 --- 太麻烦,建议用方法二*/
/*DLTNode *cur = _head->_next;
while (cur->_next != _head)
cur = cur->_next;
cur->_next = newNode;
newNode->_prev = cur;
newNode->_next = _head;
_head->_prev = newNode;*/
/* 方法二:逆向找出最后一个节点,即最后一个节点为 _head->_prev */
DLTNode *end = _head->_prev;
end->_next = newNode;
newNode->_prev = end;
_head->_prev = newNode;
newNode->_next = _head;
}
// 双向链表尾删
void DList::PopBack()
{
assert(_head->_next != _head);
DLTNode *end = _head->_prev;
_head->_prev = end->_prev;
end->_prev->_next = _head;
free(end);
}
// 双向链表头插
void DList::PushFront(DLTDataType val)
{
DLTNode *newNode = createNode(val);
DLTNode *next = _head->_next;
_head->_next = newNode;
newNode->_prev = _head;
newNode->_next = next;
next->_prev = newNode;
}
// 双向链表头删
void DList::PopFront()
{
assert(_head->_next != _head);
DLTNode *next = _head->_next;
_head->_next = next->_next;
next->_next->_prev = _head;
free(next);
}
// 双向链表查找 -- 默认正向查找
DLTNode* DList::Find(DLTDataType val)
{
assert(_head->_next != _head);
DLTNode *node = _head;
while (node->_next != _head)
{
if (node->_val == val)
return node;
node = node->_next;
}
return NULL;
}
// 双向链表在pos的前面进行插入
void DList::Insert(DLTNode* pos, DLTDataType val)
{
assert(_head->_next != _head || pos != NULL || pos != pos->_next);
DLTNode *newNode = createNode(val);
DLTNode *prev = pos->_prev;
prev->_next = newNode;
newNode->_prev = prev;
newNode->_next = pos;
pos->_prev = newNode;
}
// 双向链表删除pos位置的节点
void DList::Erase(DLTNode* pos)
{
assert(_head->_next != _head || pos != NULL || pos != pos->_next);
DLTNode *prev = pos->_prev;
DLTNode *next = pos->_next;
prev->_next = next;
next->_prev = prev;
free(pos);
}
// 双向链表销毁
void DList::Destory()
{
DLTNode *cur = _head->_next;
while (cur != _head)
{
DLTNode *next = cur->_next;
free(cur);
cur = next;
}
free(_head);
_head = NULL;
cout << "销毁结束" << endl;
}
void test()
{
DList l1;
/* 实验尾插 */
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.Print(); // 1 2 3 4
/* 实验尾删 */
l1.PopBack();
l1.Print(); // 1 2 3
l1.PopBack();
l1.Print(); // 1 2
l1.PopBack();
l1.Print(); // 1
//l1.PopBack();
//l1.Print(); // 此时会警告,因为 assert()
/* 实验头插 */
l1.PushFront(2);
l1.PushFront(3);
l1.PushFront(4);
l1.Print(); // 4 3 2 1
/* 实验头删 */
l1.PopFront();
l1.Print(); // 3 2 1
//l1.PopFront();
//l1.Print(); // 2 1
//l1.PopFront();
//l1.Print(); // 1
l1.PopFront();
l1.Print(); // 此时会警告,因为 assert()
/* 实验find */
DLTNode *node = l1.Find(2);
l1.NodePrint(node);
/* 实验任插 */
l1.Insert(node, 222);
l1.Print();// 3 222 2 1
l1.Insert(node, 555);
l1.Print();// 3 222 555 2 1
/* 实验任删 */
l1.Erase(node);
l1.Print();// 3 222 555 1
l1.Destory();
}
int main()
{
test();
system("pause");
return 0;
}
(3)运行结果