单向循环链表的实现,用C++封装,先简单给出单项循环链表的算法(具体请参考本人的另一篇博文——单链表的实现),最后给出链表C++实现的代码并测试。单循环链表和单链表的实现大部分都相同,仅遍历条件等需要修改。
定义单循环链表的节点类
//定义节点
class Node
{
public:
//数据域
double data;
//指针域
class Node *next;
};
在构造函数中使用尾插法生成单循环链表,也可以将初始化和生成链表的操作另写成一个函数。首先将类的私有数据节点(头结点)初始化;生成两个局部变量用于操作节点;使p指针始终指向尾节点;没生成一个新节点便将它连接到尾节点后并重新使p指向新的尾节点。
定义链表类,并申明私有数据成员。成员函数如下。
//构建循环链表(尾插法)
List(double a[], int n){
Node *p, *s;
int i;
L = (Node *)malloc(sizeof(Node));
p = L;//使p始终指向尾节点
for (i = 0; i < n; i++){
s = (Node *)malloc(sizeof(Node));
//读入数据
s->data = a[i];
//链接
p->next = s;
//p指向新的尾节点
p = s;
}
//将最后的尾节点的指针域赋值成空
p->next = L;
}
判断是否为空,若为空则头结点的指针域的值应为空
//是否为空
bool isEmpty(){
return (L->next == NULL);
}
在析构函数中释放单循环链表,注意判断条件与单链表的区别
//析构
~List(){
//pre和p起始位置没有限制
Node *pre = L->next, *p = pre->next;
Node *s = L->next;//第一个数据节点
while (p->next!=s){
free(pre);
pre = p;
p = p->next;
}
free(pre);
}
输出链表中的所有数据
//输出
void DisplayList(){
//讨论不同情况
if (isEmpty()){
cout << "Empty." << endl;
}
else{
//指向头第一个数据结点
Node *p = L->next, *s = L->next;
//自身地址(非遍历指针)不等于自身地址(遍历指针)
while (p->next != s){
cout << p->data << ends;
p = p->next;
}
cout << endl;
}
}
在某一位置插入
//插入
bool NodeInsert(int i, double elem){
//讨论两种情况
if (isEmpty()){
return false;
}
else{
i--;//找到前一节点
Node *p = L, *s = L, *pn;
int j = 0;
//找到位置
while (i != j&&p->next != s){
j++;
p = p->next;
}
if (i != j&&p->next == s){
return false;
}
//插入
else{
pn = (Node *)malloc(sizeof(Node));
pn->data = elem;
pn->next = p->next;
p->next = pn;
return true;
}
}
}
查找对应序号下的值并取出该值
//按序号查找并返回值
bool GetElem(int i, double &elem){
Node *p = L, *s = L;
int j = 0;
if (isEmpty()){
return false;
}
else{
//找到位置
while (i!=j&&p->next != s){
j++;
p = p->next;
}
if (i != j&&p->next == s){
return false;
}
else{
//赋值结果
elem = p->data;
return true;
}
}
}
判断单向循环链表中是否存在某一值,存在则返回第一个与之匹配的序号
//按值查找并返回序号
bool LocatElem(int &i, double elem){
if (isEmpty()){
return false;
}
else{
Node *p = L, *s = L;
int j = 0;
//遍历搜索
while (elem!=p->data&&p->next != s){
j++;
p = p->next;
}
if (elem != p->data&&p->next == s){
return false;
}
else{
//找到位置并传出值
i = j;
return true;
}
}
}
删除指定节点
//删除节点
bool DeleteNode(int i){
if (isEmpty()){
return false;
}
else{
i--;
Node *p, *s = L, *pn = L;
int j = 0;
//遍历搜索
while (i!=j&&pn->next != s){
j++;
pn = pn->next;
}
if (i!=j&&pn->next == s){
return false;
}
else{
//释放空间
p = pn->next;
pn->next = pn->next->next;
free(p);
return true;
}
}
}
C++封装的完整代码如下:
/*
单循环链表
*/
#include<iostream>
using namespace std;
const int MAX_N = 100;
//定义节点
class Node
{
public:
//数据域
double data;
//指针域
class Node *next;
};
class List
{
public:
//构建循环链表(尾插法)
List(double a[], int n){
Node *p, *s;
int i;
L = (Node *)malloc(sizeof(Node));
p = L;//使p始终指向尾节点
for (i = 0; i < n; i++){
s = (Node *)malloc(sizeof(Node));
//读入数据
s->data = a[i];
//链接
p->next = s;
//p指向新的尾节点
p = s;
}
//将最后的尾节点的指针域赋值成空
p->next = L;
}
//是否为空
bool isEmpty(){
return (L->next == NULL);
}
//析构
~List(){
//pre和p起始位置没有限制
Node *pre = L->next, *p = pre->next;
Node *s = L->next;//第一个数据节点
while (p->next!=s){
free(pre);
pre = p;
p = p->next;
}
free(pre);
}
//输出
void DisplayList(){
//讨论不同情况
if (isEmpty()){
cout << "Empty." << endl;
}
else{
//指向头第一个数据结点
Node *p = L->next, *s = L->next;
//自身地址(非遍历指针)不等于自身地址(遍历指针)
while (p->next != s){
cout << p->data << ends;
p = p->next;
}
cout << endl;
}
}
//插入
bool NodeInsert(int i, double elem){
//讨论两种情况
if (isEmpty()){
return false;
}
else{
i--;//找到前一节点
Node *p = L, *s = L, *pn;
int j = 0;
//找到位置
while (i != j&&p->next != s){
j++;
p = p->next;
}
if (i != j&&p->next == s){
return false;
}
//插入
else{
pn = (Node *)malloc(sizeof(Node));
pn->data = elem;
pn->next = p->next;
p->next = pn;
return true;
}
}
}
//按序号查找并返回值
bool GetElem(int i, double &elem){
Node *p = L, *s = L;
int j = 0;
if (isEmpty()){
return false;
}
else{
//找到位置
while (i!=j&&p->next != s){
j++;
p = p->next;
}
if (i != j&&p->next == s){
return false;
}
else{
//赋值结果
elem = p->data;
return true;
}
}
}
//按值查找并返回序号
bool LocatElem(int &i, double elem){
if (isEmpty()){
return false;
}
else{
Node *p = L, *s = L;
int j = 0;
//遍历搜索
while (elem!=p->data&&p->next != s){
j++;
p = p->next;
}
if (elem != p->data&&p->next == s){
return false;
}
else{
//找到位置并传出值
i = j;
return true;
}
}
}
//删除节点
bool DeleteNode(int i){
if (isEmpty()){
return false;
}
else{
i--;
Node *p, *s = L, *pn = L;
int j = 0;
//遍历搜索
while (i!=j&&pn->next != s){
j++;
pn = pn->next;
}
if (i!=j&&pn->next == s){
return false;
}
else{
//释放空间
p = pn->next;
pn->next = pn->next->next;
free(p);
return true;
}
}
}
private:
Node *L;
};
int main()
{
double a[MAX_N], res = 0;
int n,i = 0;
cout << "Input n:";
cin >> n;
for (i = 0; i < n; i++){
cin >> a[i];
}
List m_list(a,n);
m_list.DisplayList();
cout << "Input i,element:";
cin >> i >> res;
m_list.NodeInsert(i,res);
m_list.DisplayList();
cout << "Input i:";
cin >> i;
if (m_list.GetElem(i, res)){
cout << "Location " << i << " , element: ";
cout << res << endl;
}
else{
cout << "error." << endl;
}
cout << "Input element:";
cin >> res;
if (m_list.LocatElem(i, res)){
cout << "element: " << res << " , location: ";
cout << i << endl;
}
else{
cout << "error." << endl;
}
cout << "Input Location i for delete:";
cin >> i;
if (m_list.DeleteNode(i)){
cout << "Location " << i << " is deleted." << endl;
m_list.DisplayList();
}
else{
cout << "error." << endl;
}
return 0;
}
测试运行: