双向链表常用操作的代码实现
双链表的常用操作:创建、遍历、插入、删除、判断等
部分运行效果图片:
完整的代码片段
.
/************************************************
双链表的常用操作:创建、遍历、插入、删除、判断等
************************************************/
#include<stdio.h>
#include<stdlib.h> //提供malloc()和free()
#include<iomanip>
//#include "stdafx.h"
#include<iostream>
using namespace std;
typedef int DataType;
#define Node ElemType
#define ERROR NULL
//构建一个节点类
class Node
{
public:
int data;
Node * pre;
Node * next;
};
//构建一个双链表类
class LinkList
{
public:
LinkList();
~LinkList();
void CreateLinkList(int n);
void TravalLinkList();
int GetLength();
bool IsEmpty();
ElemType * Find(DataType data);
void InsertElemAtEnd(DataType data);
void InsertElemAtIndex(DataType data, int n);
void InsertElemAtHead(DataType data);
void DeleteElemAtEnd();
void DeleteAll();
void DeleteElemAtPoint(DataType data);
void DeleteElemAtHead();
private:
ElemType * head;
};
//初始化双链表
LinkList::LinkList()
{
head = new ElemType;
head->data = 0;
head->pre = NULL;
head->next = NULL;
}
//销毁双链表
LinkList::~LinkList()
{
delete head;
}
//创建一个双链表
void LinkList::CreateLinkList(int n)
{
ElemType *pnew, *ptemp;
ptemp = head;
if (n <= 0) { //当输入的值有误时,处理异常
cout << "输入的节点个数有误" << endl;
exit(EXIT_FAILURE);
}
for(int i = 0; i < n; i++) { //将值一个一个的插入链表中
pnew = new ElemType;
cout << "请输入第" << i + 1 << "个值" ;
cin >> pnew->data;
pnew->pre = ptemp; //将新建节点的头指针指向当前节点
pnew->next = ptemp->next; //将新建节点的尾指针指向当前节点的下一个节点
ptemp->next = pnew; //将当前节点的下一节点指向新建节点
ptemp = pnew; //当前节点指向新建节点
}
cout << "请输入数字进行选择:" << endl;
}
//遍历双链表
void LinkList::TravalLinkList()
{
if(head==NULL || head->next == NULL) {
cout << "链表为空" <<endl;
}
ElemType *p = head;
while (p->next != NULL)
{
p = p->next;
cout << p->data << " " ;
}
}
//获取双链表的长度
int LinkList::GetLength()
{
int count = 0;
ElemType *p = head->next;
while (p != NULL)
{
count++;
p = p->next;
}
return count;
}
//判断双链表是否为空
bool LinkList::IsEmpty()
{
if (head->next == NULL)
{
return true;
}
return false;
}
//查找节点
ElemType * LinkList::Find(DataType data)
{
ElemType * p = head;
if (p == NULL || p->next == NULL) { //当链表为空时报异常
cout << "链表为空!" << endl;
return ERROR;
}
else
{
while (p->next != NULL) //循环每一个节点
{
if (p->data == data) { //返回指针域
return p;
}
p = p->next;
}
cout << "未找到数据" ; //未查询到结果
}
return NULL;
}
//在尾部插入指定元素
void LinkList::InsertElemAtEnd(DataType data)
{
ElemType * newNode = new ElemType; //定义一个Node节点指针newNode
newNode->next = NULL;
newNode->data = data;
ElemType * p = head;
if (head == NULL) {
head = newNode;
}
else
{
while (p->next != NULL)
{
p = p->next;
}
newNode->pre = p;
newNode->next = p->next;
p->next = newNode;
}
}
//在头部插入指定元素
void LinkList::InsertElemAtHead(DataType data)
{
ElemType * newNode = new ElemType; //定义一个Node节点指针newNode
newNode->data = data;
ElemType * p = head;
if (head == NULL) {
head = newNode;
}
newNode->next = p->next;
newNode->pre = p;
p->next = newNode;
}
//在指定位置插入指定元素
void LinkList::InsertElemAtIndex(DataType data, int n)
{
if( n < 1 || n > GetLength() ) //输入有误报异常
cout << "输入的值有误" << endl;
else
{
int i = 1;
ElemType * ptemp = new ElemType; //定义一个新的节点
ptemp->data = data; //新建节点数据域赋值
ElemType *p = head; //创建一个指针指向头节点
while (n > i)
{
p = p->next;
i++;
}
ptemp->next = p->next;
p->next->pre = ptemp;
ptemp->pre = p;
p->next = ptemp;
cout << "数据插入成功" << endl;
}
}
//删除尾部节点元素
void LinkList::DeleteElemAtEnd()
{
ElemType * ptemp = NULL; //创建一个占位节点
ElemType * p = head; //创建指针指向头节点
if (NULL == p)
cout << "链表为空" << endl;
else
{
while (p->next != NULL)
{
ptemp = p;
p = p->next;
}
delete p;
p = NULL;
ptemp->next = NULL;
}
}
//删除链表所有元素,保留头节点
void LinkList::DeleteAll()
{
ElemType * p = head->next;
ElemType * ptemp = new ElemType;
while(p->next != NULL)
{
ptemp = p->next;
p->next = NULL;
p->pre = NULL;
delete p;
p = NULL;
p = ptemp;
}
head->next = NULL; //头节点的下一节点指向NULL
}
//删除指定元素节点
void LinkList::DeleteElemAtPoint(DataType data)
{
ElemType * ptemp = Find(data);
if (NULL == ptemp)
cout << "未找到元素:" << data << endl;
else if (ptemp->next == NULL)
{ //要删除的元素是链表最后一个节点
ptemp->pre->next = ptemp->next;
ptemp->pre = NULL;
delete ptemp;
ptemp = NULL;
cout << "元素已删除" << endl;
}
else
{ //要删除的元素不是链表最后一个元素
ptemp->pre->next = ptemp->next;
ptemp->next->pre = ptemp->pre;
ptemp->next = NULL;
ptemp->pre = NULL;
delete ptemp;
ptemp = NULL;
cout << "元素已删除" << endl;
}
}
void LinkList::DeleteElemAtHead() { //删除头部节点
ElemType * p = head;
if (p==NULL || p->next == NULL) {
cout << "链表为空" <<endl;
}
else {
ElemType * ptemp = NULL;
p = p->next;
ptemp = p->next;
ptemp->pre = p->pre;
delete p;
head->next = ptemp;
cout << "头元素删除成功!" << endl;
}
}
int main()
{
LinkList l;
int i;
DataType data;
cout << "1.创建双链表" << endl;
cout << "2.遍历双链表" << endl;
cout << "3.获取链表长度" << endl;
cout << "4.判断链表是否为空" << endl;
cout << "5.查找元素" << endl;
cout << "6.在链表尾部插入元素" << endl;
cout << "7.在指定位置插入元素" << endl;
cout << "8.在头部插入元素" << endl;
cout << "9.删除尾部元素" << endl;
cout << "10.删除所有元素" << endl;
cout << "11.删除指定元素" << endl;
cout << "12.删除头部元素" << endl;
cout << "0.退出" << endl;
do
{
cin>>i;
switch(i)
{
case 1:
int n;
cout << "请输入链表长度:" <<endl;
cin >> n;
l.CreateLinkList(n);
break;
case 2:
l.TravalLinkList();
cout << "请输入数字进行选择:" << endl;
break;
case 3:
cout << "该双链表长度为:" << l.GetLength() << endl;
cout << "请输入数字进行选择:" << endl;
break;
case 4:
if(l.IsEmpty() == 1)
{
cout << "该双链表为空表" << endl;
}
else
{
cout << "该双链表不为空" << endl;
}
break;
case 5:
cout << "请输入要查找的元素" << endl;
cin >> data;
if (l.Find(data) != NULL && l.Find(data) != ERROR)
{
cout << "要查找的元素的值是:" << l.Find(data)->data << endl;
cout << "请输入数字进行选择:" << endl;
}
else
{
cout<<endl;
cout << "请输入数字进行选择:" << endl;
}
break;
case 6:
cout << "请输入要在尾部插入的元素" << endl;
cin >> data;
l.InsertElemAtEnd(data);
cout << "请输入数字进行选择:" << endl;
break;
case 7:
cout << "请输入要插入的元素的位置:" << endl;
cin >> n;
cout << "请输入要插入的元素" << endl;
cin >> data;
l.InsertElemAtIndex(data,n);
break;
case 8:
cout << "请输入要在头部插入的元素值:" << endl;
cin >> data;
l.InsertElemAtHead(data);
break;
case 9:
l.DeleteElemAtEnd();
break;
case 10:
l.DeleteAll();
break;
case 11:
cout << "请输入要删除的元素值:" << endl;
cin >> data;
l.DeleteElemAtPoint(data);
break;
case 12:
l.DeleteElemAtHead();
break;
default:
break;
}
}
while (i != 0);
system("pause");
return 0;
}