双链表的实现C++封装
2015-10-03 12:22
399 查看
双链表的C++实现,先给出主要算法,最后而给出完整的实现。
定义节点
头插法插入元素节点
尾插法插入节点
判断是否为空
以上便是完整的双链表算法C++实现,下面附上完整代码
测试运行结果
定义节点
//定义节点 typedef class Node { public: //数据 int data; //前指针 class Node *prior; //后指针 class Node *next; }ListNode;
头插法插入元素节点
//创建并初始化(头插法) List(int a[], int n){ int i; ListNode *p; L = (ListNode *)malloc(sizeof(ListNode)); L->next = L->prior = NULL; for (i = 0; i < n; i++){ p = (ListNode *)malloc(sizeof(ListNode)); p->data = a[i]; p->next = L->next;//将p后一个节点地址赋给l->next if (L->next != NULL){ L->next->prior = p;//将L后一节点的前指针赋值为带插入指针地址 } p->prior = L;//带插入前指针赋值为L L->next = p;//L后指针赋值为p } }
尾插法插入节点
//尾插法 List(int a[], int n){ int i; ListNode *p, *s; //初始化表头 L = (ListNode *)malloc(sizeof(ListNode)); L->prior = NULL; //使p指向尾节点,初始时头结点即为尾节点 p = L; //生成新节点,插入元素,链上节点 for (i = 0; i < n; i++){ s = (ListNode *)malloc(sizeof(ListNode)); s->data = a[i]; //前指针指向尾结点 s->prior = p; //尾指针指向新节点 p->next = s; //将新节点变成为节点 p = s; } p->next = NULL; }释放双链表
//析构并释放空间 ~List(){ ListNode *pre = L, *p = L->next; while (p != NULL){ free(pre); pre = p; p = pre->next;//p指向下下个节点 } free(pre);//下个节点 }
判断是否为空
//判断是否为空 bool isEmpty(){ return (L->next == NULL); }返回链表长度
//返回长度 int GetLength(){ int i = 0; ListNode *p = L; while (p->next != NULL){//p->next为当前节点的指针域 i++; p = p->next; } return i; }输出链表元素
//输出链表 void DispleyList(){ ListNode *p = L->next; while (p != NULL){ cout << p->data << ends; p = p->next; } cout << endl; }按元素位置查找并返回值
//按序号查找并返回值 bool getElem(int i, int &res){ ListNode *p = L; int j = 0; while (j != i&&p->next != NULL){ j++; p = p->next; } //讨论退出的情况 if (j != i&&p->next == NULL){ return false; } else{ res = p->data; return true; } }按值查找并返回位置
//按值查找并返回序号 int LocateElem(int elem){ ListNode *p = L; int i = 0; while (p->next != NULL&&p->data!=elem){ i++; p = p->next; } //讨论退出的情况 if (p->next == NULL&&p->data != elem){ return 0; } else{ return i; } }插入新节点
//插入元素 void InsertElem(int i, int &res){ i--;//找到插入位置的前一个节点 int j = 0; ListNode *p = L, *s; while (j != i&&p->next != NULL){ j++; p = p->next; } //讨论退出情况 if (j != i&&p->next == NULL){ cout << "error No." << endl; } else{ s = (ListNode *)malloc(sizeof(ListNode)); s->data = res; //链上后继节点,当前节点的指针域赋值为p的后继节点 s->next = p->next; //插入当前节点,下一节点的前指针指向当前节点 p->next->prior = s; //p的后指针域赋值为当前节点 p->next = s; //当前节点的前指针赋值为p s->prior = p; } }删除某一节点
//删除元素并返回值 bool DeleteElem(int i,int &res){ i--; ListNode *p = L, *s; int j = 0; while (j != i&&p->next != NULL){ j++; p = p->next; } if (j != i&&p->next == NULL){ return false; } else{ //记录p的下一个节点的地址 s = p->next; //得到数据 res = s->data; //p的后指针域存储p的下一个的下一个节点 p->next = p->next->next; //p的下一个的下一个节点的前指针域赋值为p的地址 p->next->next->prior = p; //释放 free(s); return true; } }
以上便是完整的双链表算法C++实现,下面附上完整代码
#include<iostream>
using namespace std;
const int MAX_N = 100;
//定义节点 typedef class Node { public: //数据 int data; //前指针 class Node *prior; //后指针 class Node *next; }ListNode;
class List
{
public:
//创建并初始化(头插法)
//List(int a[], int n){
// int i;
// ListNode *p;
// L = (ListNode *)malloc(sizeof(ListNode));
// L->next = L->prior = NULL;
// for (i = 0; i < n; i++){
// p = (ListNode *)malloc(sizeof(ListNode));
// p->data = a[i];
// p->next = L->next;//将p后一个节点地址赋给l->next
// if (L->next != NULL){
// L->next->prior = p;//将L后一节点的前指针赋值为带插入指针地址
// }
// p->prior = L;//带插入前指针赋值为L
// L->next = p;//L后指针赋值为p
// }
//}
//尾插法
List(int a[], int n){
int i;
ListNode *p, *s;
//初始化表头
L = (ListNode *)malloc(sizeof(ListNode));
L->prior = NULL;
//使p指向尾节点,初始时头结点即为尾节点
p = L;
//生成新节点,插入元素,链上节点
for (i = 0; i < n; i++){
s = (ListNode *)malloc(sizeof(ListNode));
s->data = a[i];
//前指针指向尾结点
s->prior = p;
//尾指针指向新节点
p->next = s;
//将新节点变成为节点
p = s;
}
p->next = NULL;
}
//析构并释放空间 ~List(){ ListNode *pre = L, *p = L->next; while (p != NULL){ free(pre); pre = p; p = pre->next;//p指向下下个节点 } free(pre);//下个节点 }
//判断是否为空
bool isEmpty(){
return (L->next == NULL);
}
//返回长度
int GetLength(){
int i = 0;
ListNode *p = L;
while (p->next != NULL){//p->next为当前节点的指针域
i++;
p = p->next;
}
return i;
}
//输出链表
void DispleyList(){
ListNode *p = L->next;
while (p != NULL){
cout << p->data << ends;
p = p->next;
}
cout << endl;
}
//按序号查找并返回值
bool getElem(int i, int &res){
ListNode *p = L;
int j = 0;
while (j != i&&p->next != NULL){
j++;
p = p->next;
}
//讨论退出的情况
if (j != i&&p->next == NULL){
return false;
}
else{
res = p->data;
return true;
}
}
//按值查找并返回序号
int LocateElem(int elem){
ListNode *p = L;
int i = 0;
while (p->next != NULL&&p->data!=elem){
i++;
p = p->next;
}
//讨论退出的情况
if (p->next == NULL&&p->data != elem){
return 0;
}
else{
return i;
}
}
//插入元素
void InsertElem(int i, int &res){
i--;//找到插入位置的前一个节点
int j = 0;
ListNode *p = L, *s;
while (j != i&&p->next != NULL){
j++;
p = p->next;
}
//讨论退出情况
if (j != i&&p->next == NULL){
cout << "error No." << endl;
}
else{
s = (ListNode *)malloc(sizeof(ListNode));
s->data = res;
//链上后继节点,当前节点的指针域赋值为p的后继节点
s->next = p->next;
//插入当前节点,下一节点的前指针指向当前节点
p->next->prior = s;
//p的后指针域赋值为当前节点
p->next = s;
//当前节点的前指针赋值为p
s->prior = p;
}
}
//删除元素并返回值
bool DeleteElem(int i,int &res){
i--;
ListNode *p = L, *s;
int j = 0;
while (j != i&&p->next != NULL){
j++;
p = p->next;
}
if (j != i&&p->next == NULL){
return false;
}
else{
//记录p的下一个节点的地址
s = p->next;
//得到数据
res = s->data;
//p的后指针域存储p的下一个的下一个节点
p->next = p->next->next;
//p的下一个的下一个节点的前指针域赋值为p的地址
p->next->next->prior = p;
//释放
free(s);
return true;
}
}
private:
ListNode *L;
};
int main(){
int i, n, a[MAX_N], res = 0;
cout << "Input length:";
cin >> n;
for (i = 0; i < n; i++){
cin >> a[i];
}
//构建单链表
List m_list(a, n);
//输出
m_list.DispleyList();
//判断是否为空,非空输出长度
if (!m_list.isEmpty()){
cout << "It is not empty." << endl;
cout << "It contained " << m_list.GetLength() << " elements." << endl;
}
else{
cout << "It is empty." << endl;
}
//按序号查找并返回值
cout << "Input a number for querry:";
cin >> i;
if (m_list.getElem(i, res)){
cout << "Location: " << i << " ,element: " << res << endl;
}
else{
cout << "Loaction " << i << " is invalid." << endl;
}
//按值查找并返回序号
cout << "Input a element for querry:";
cin >> res;
if (m_list.LocateElem(res) == 0){
cout << "Not contain this element." << endl;
}
else{
cout << "Element: " << res << " ,No. is :" << m_list.LocateElem(res) << endl;
}
//插入
cout << "Input NO. and element for insert:";
cin >> i >> res;
m_list.InsertElem(i, res);
m_list.DispleyList();
//删除
cout << "Input NO. for delete:";
cin >> i;
if (!m_list.DeleteElem(i, res)){
cout << "Invalid NO." << endl;
}
else{
cout << "NO. :" << i << " ,Element: " << res << " is deleted." << endl;
}
m_list.DispleyList();
return 0;
}
测试运行结果
相关文章推荐
- C/C++语言中的函数参数传参三种对比
- c++ primer 练习5.25
- C++学习(一)-纯虚函数和抽象类(4)
- 单链表的实现C++封装
- c++的引用
- C2第一次作业
- C++学习(一)- 虚函数和重载函数的区别(3)
- 【C++】c++复数类Complex
- 指针做函数参数——高效C语言
- 【Cpp】删除字符串空格
- Bjarne Stroustrup announces C++ Core Guidelines
- 顺序表的实现C++封装
- c++ primer 练习5.22
- c语言的正则表达式
- c++ primer 练习5.21
- C语言中函数参数为什么是由右往左入栈的?
- c++ primer 练习5.20
- C/C++堆区、栈区、常量区、静态数据区、代码区详解
- C++ STL vector assign用法
- C语言快速入门系列-详解