该文章主要介绍线性表的链式存储运算以及相关运算—循环单链表。
头文件:CLinkList.h
template <typename T>
struct LinkList //循环单链表结点类型
{
T data; //存放数据元素
LinkList<T> *next; //指向下一个结点的域
};
template <typename T>
class CLinkListClass //循环单链表类
{
LinkList<T> *head; //循环单链表头结点
public:
//=================循环单链表的基本运算算法========================
CLinkListClass<T>(); //构造函数,创建一个空循环单链表
~CLinkListClass<T>(); //析构函数,销毁循环单链表
void CreateListF(T a[], int n); //头插法建立循环单链表
void CreateListR(T a[], int n); //尾插法建立循环单链表
void DispList(); //输出循环单链表所有结点值
int ListLength(); //求循环单链表数据结点个数
bool GetElem(int i, T &e); //求循环单链表中某个数据元素值
int LocateElem(T e); //按元素值查找
bool ListInsert(int i, T e); //插入数据元素
bool ListDelete(int i); //删除数据元素
//=================循环单链表的其他运算算法========================
template <typename C>
friend int Count(CLinkListClass<C> &L, C x); //统计循环单链表值为x的个数
template <typename C>
friend void Comb(CLinkListClass<C> &L1, CLinkListClass<C> &L2);//将L2接到L1后面,使L1成为循环单链表
};
源文件:CLinkList.cpp
#include <iostream>
#include "CLinkList.h"
//======================循环单链表的基本运算算法=======================
template <typename T>
CLinkListClass<T>::CLinkListClass<T>() //构造函数,创建一个空循环单链表
{
head = new LinkList<T>();
head->next = head;
}
template <typename T>
CLinkListClass<T>::~CLinkListClass<T>() //析构函数,销毁循环单链表
{
//===该下注释释放链表感觉有问题,但没报错!
/*LinkList<T> *pre = head, *p = pre->next;
while (p != head)
{
delete pre;
pre = p;
p = p->next;
}
delete pre;*/
//===该下释放链表无问题!
LinkList<T> *p = head->next, *q = p;
while (p != head)
{
p = p->next;
delete q;
q = p;
}
delete q;
}
template <typename T>
void CLinkListClass<T>::CreateListF(T a[], int n) //头插法建立循环单链表
{
LinkList<T> *s;
int i;
head->next = head;
for (i = 0; i<n; i++)
{
s = new LinkList<T>();
s->data = a[i];
s->next = head->next;
head->next = s;
}
}
template <typename T>
void CLinkListClass<T>::CreateListR(T a[], int n) //尾插法建立循环单链表
{
LinkList<T> *s, *r;
int i;
r = head;
for (i = 0; i<n; i++)
{
s = new LinkList<T>();
s->data = a[i];
r->next = s;
r = s;
}
r->next = head;
}
template <typename T>
void CLinkListClass<T>::DispList() //输出循环单链表所有结点值
{
LinkList<T> *p;
p = head->next;
while (p != head)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
template <typename T>
int CLinkListClass<T>::ListLength() //求循环单链表数据结点个数
{
int i = 0;
LinkList<T> *p;
p = head;
while (p->next != head)
{
i++;
p = p->next;
}
return(i);
}
template <typename T>
bool CLinkListClass<T>::GetElem(int i, T &e)//求循环单链表中某个数据元素值
{
int j = 1;
LinkList<T> *p;
p = head->next;
while (j < i && p != head)
{
j++;
p = p->next;
}
if (p == head)
return false;
else
{
e = p->data;
return true;
}
}
template <typename T>
int CLinkListClass<T>::LocateElem(T e) //按元素值查找
{
int i = 1;
LinkList<T> *p;
p = head->next;
while (p != head && p->data != e)
{
p = p->next;
i++;
}
if (p == head)
return (0);
else
return (i);
}
template <typename T>
bool CLinkListClass<T>::ListInsert(int i, T e) //插入数据元素
{
int j = 0;
LinkList<T> *pre = head, *p = pre->next, *s;
if (i <= 0) return false;
while (p != head && j<i - 1)
{
j++;
pre = p;
p = p->next;
}
if (p == head && i>j + 1)
return false;
else
{
s = new LinkList<T>();
s->data = e;
s->next = pre->next;
pre->next = s;
return true;
}
}
template <typename T>
bool CLinkListClass<T>::ListDelete(int i) //删除数据元素
{
int j = 0;
LinkList<T> *p = head, *q;
if (i <= 0) return false;
while (p->next != head && j<i - 1)
{
j++;
p = p->next;
}
if (p->next == head) return false;
else
{
q = p->next;
if (q == head) return false;
else
{
p->next = q->next;
delete q;
return true;
}
}
}
//==================循环单链表的其他运算算法========================
template <typename C>
int Count(CLinkListClass<C> &L, C x)
{
int count = 0;
LinkList<C> *p = L.head ->next;
while (p != L.head)
{
if (p->data == x)
count++;
p = p->next;
}
return count;
}
template <typename C>
void Comb(CLinkListClass<C> &L1, CLinkListClass<C> &L2)
{
LinkList<C> *p1 = L1.head->next;
while (p1->next != L1.head)
{
p1 = p1->next;
}
LinkList<C> *p2 = L2.head->next;
p1->next = p2;
while (p2->next != L2.head)
{
p2 = p2->next;
}
p2->next = L1.head;
L2.head->next = L2.head;
}
主函数:main.cpp
#include "CLinkList.cpp"
using namespace std;
//================循环单链表的基本运算算法======================
void main()
{
int i,e;
int a[]={1,2,3,4,5,6};
CLinkListClass<int> L; //建立元素类型为int的循环单链表对象L
cout << "创建循环单链表L" << endl;
L.CreateListR(a,6);
cout << "循环单链表L:"; L.DispList();
cout << "长度:" << L.ListLength() << endl;
//===
i=3;
L.GetElem(i,e);
cout << "第" << i << "个元素:" << e << endl;
//===
e=1;
cout << "元素" << e << "是第" << L.LocateElem(e) << "个元素\n";
//===
i=4;
cout << "删除第" << i << "个元素\n";
L.ListDelete(i);
cout << "循环单链表L:";L.DispList();
cout << "销毁循环单链表L" << endl;
}
//===================循环单链表的其他运算算法===============
void main1()
{
CLinkListClass<int> L; //建立元素类型为int的循环单链表对象L
L.ListInsert(1,1); //插入元素1
L.ListInsert(2,3); //插入元素3
L.ListInsert(3,1); //插入元素1
L.ListInsert(4,5); //插入元素5
L.ListInsert(5,4); //插入元素4
L.ListInsert(6,2); //插入元素2
cout << "循环单链表L:";
L.DispList();
//===
int e = 0;
int count = Count(L,e);
cout << "值为" << e << "的个数:" << count << endl;
//===
int a1[] = { 1, 2, 3, 4, 5, 6 };
int a2[]={ 5, 8, 9, 3 };
CLinkListClass<int> L1;
CLinkListClass<int> L2;
L1.CreateListR(a1, 6);
L2.CreateListR(a2, 4);
cout << "循环单链表L1:"; L1.DispList();
cout << "循环单链表L2:"; L2.DispList();
Comb(L1, L2);
cout << "L2连接到L1后面,循环单链表L1:"; L1.DispList();
cout << "L2连接到L1后面,循环单链表L2:"; L2.DispList();
}