所实现的循环单链表的结构例如以下图所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

循环单链表的实现,和上一篇文章单链表的实现大致同样点击打开链接,略有差别:

1:循环推断的条件不再是s == NULL或者s->next == NULL,而是他们是否等于头指针。2: 断开链表时的处理,尾节点的next不是NULL,而是指向头结点

详细细节參考上一篇文章

头文件:SCList.h

#ifndef SCLIST_H
#define SCLIST_H #include<iostream>
#include<cassert>
using namespace std; typedef enum{ FALSE, TRUE }Status; template<class Type>
class List; template<class Type>
class ListNode
{
friend class List<Type>;
private:
Type data;
ListNode *next;
public:
ListNode() :data(Type()), next(NULL){}
ListNode(Type d, ListNode<Type> *n = NULL) :data(d), next(n){}
void SetData(Type d){ data = d; }
Type GetData()const{ return data; }
~ListNode(){}
}; template<class Type>
class List
{
private:
ListNode<Type> *first;
ListNode<Type> *last;
size_t size;
public:
List()
{
ListNode<Type> *s = new ListNode<Type>;
assert(s != NULL);
first = last = s;
last->next = first;
}
~List()
{
destory();
}
Status push_back(const Type &x)
{
ListNode<Type> *s = new ListNode<Type>(x);
if (s == NULL)
return FALSE;
last->next = s;
last = s;
last->next = first;
size++;
return TRUE;
}
void show_list()
{
ListNode<Type> *s = first->next;
while (s != first)
{
cout << s->data << "->";
s = s->next;
}
cout << "Nul." << endl;
}
Status push_front(const Type &x)
{
ListNode<Type> *s = new ListNode<Type>(x);
if (s == NULL)
return FALSE;
s->next = first->next;
first->next = s;
if (size == 0)
{
last = s;
last->next = first;//---------------->能够省略,think
}
size++;
return TRUE;
}
Status pop_back()
{
if (size == 0)//
{
cout << "循环单链表已空,无法尾删" << endl;
return FALSE;
}
ListNode<Type> *s = first;
while (s->next != last)
s = s->next;
delete last;
last = s;
last->next = first;
size--;
return TRUE;
}
Status pop_front()
{
if (size == 0)//
{
cout << "循环单链表已空。无法头删" << endl;
return FALSE;
}
ListNode<Type> *s = first->next;
first->next = s->next;
delete s;
if (size == 1)
{
last = first;
last->next = first;//能够省略-------------->
}
size--;
return TRUE;
}
Status insert_val(const Type &x)
{
ListNode<Type> *s = first;
while (s->next != first && s->next->data < x)
s = s->next;
if (s->next == first)
push_back(x);
else
{
ListNode<Type> *p = new ListNode<Type>(x);
assert(p != NULL);
p->next = s->next;
s->next = p;
size++;
}
return TRUE;
}
ListNode<Type>* find(const Type &x)
{
if (size == 0)
return NULL;
ListNode<Type> *s = first->next;
while (s != first)
{
if (s->data == x)
return s;
s = s->next;
}
return NULL;
}
Status delete_val(const Type &x)
{
ListNode<Type> *s = find(x);
if (s == NULL)
{
cout << "该元素不存在,无法删除" << endl;
return FALSE;
}
if (s == last)
{
pop_back();
}
else
{
ListNode<Type> *p = s->next;
s->data = p->data;
s->next = p->next;
if (p == last)//------------------->>注意
{
last = s;
}
delete p;
size--;
}
return TRUE;
}
//从第一个节点处断开,一分为二,头结点和第一个节点成为一个单独的循环单链表
//将剩余的节点依次按值插入该链表
void sort()
{
if (size == 0 || size == 1)
return;
ListNode<Type> *s = first->next;
ListNode<Type> *p = s->next;
last = s;
last->next = first;
while (p != first)
{
s = p;
p = p->next;
//insert_val(s->data);
//delete s;
ListNode<Type> *q = first;
while (q->next != NULL && q->next->data < s->data)
{
q = q->next;
}
if (q->next == NULL)
{
last->next = s;
last = s;
last->next = first;
}
else
{
s->next = q->next;
q->next = s;
}
}
}
//从第一个节点处断开,一分为二,头结点和第一个节点成为一个单独的循环单链表
//将剩余的节点依次进行头插
void reserve()
{
if (size == 0 || size == 1)
return;
ListNode<Type> *s = first->next;
ListNode<Type> *p = s->next;
last = s;
last->next = first;
while (p != first)
{
s = p;
p = p->next;
s->next = first->next;
first->next = s;
}
}
size_t lenth()
{
return size;
}
void clear()
{
if (size == 0)
return;
ListNode<Type> *s = first->next;
while (s != first)
{
if (size == 1)
{
last = first;
last->next = first;
}
else
{
first->next = s->next;
}
delete s;
size--;
s = first->next;
}
}
ListNode<Type>* next(ListNode<Type> *s)
{
if (s == last)//最后一个节点没有后继
return NULL;
else
return s->next;
}
ListNode<Type>* prio(ListNode<Type> *s)
{
if (s == first->next)//第一个节点没有前驱
return NULL;
ListNode<Type> *p = first;
while (p->next != s)
{
p = p->next;
}
return p;
}
void destory()
{
clear();
delete first;
first = last = NULL;
}
};
#endif

測试文件:main.cpp

#include"SCList.h"

int main()
{
List<int> mylist;
int item;
int n;
int select = 1;
//ListNode<int> *p;
while (select)
{
cout << "*************************************** *" << endl;
cout << "*[1] push_back [2] push_front *" << endl;
cout << "*[3] show_list [4] pop_back *" << endl;
cout << "*[5] pop_front [6] insert_val *" << endl;
cout << "*[7] lenth [8] find *" << endl;
cout << "*[9] merge [10] delete_val*" << endl;
cout << "*[11] sort [12] reserve *" << endl;
cout << "*[13] next [14] clear *" << endl;
cout << "*[15] prio [0] quit_system*" << endl;
cout << "请选择:>";
cin >> select;
switch (select)
{
case 1:
cout << "请输入要插入的元素(-1结束):>";
while (cin >> item, item != -1)
{
mylist.push_back(item);
}
break;
case 2:
cout << "请输入要插入的元素(-1结束):>";
while (cin >> item, item != -1)
{
mylist.push_front(item);
}
break;
case 3:
mylist.show_list();
break;
case 4:
mylist.pop_back();
break;
case 5:
mylist.pop_front();
break;
case 6:
cout << "请输入要插入的元素:";
cin >> item;
mylist.insert_val(item);
break;
case 7:
cout << "长度为:" << mylist.lenth() << endl;
break;
case 8:
cout << "请输入要查找的元素:";
cin >> item;
if (mylist.find(item))
cout << "it's found" << endl;
else
cout << "it's not exist" << endl;
break;
case 9:
cout << "请输入要删除的位置:";
cin >> n;
//mylist.delete_pos(n,item);
break;
case 10:
cout << "请输入要删除的元素:";
cin >> item;
mylist.delete_val(item);
break;
case 11:
mylist.sort();
break;
case 12:
mylist.reserve();
break;
case 13:
cout << "请输入要查找后继的元素:";
cin >> item;
//p = mylist.next(item);
//if (p != NULL)
// cout << p->GetData() << endl;
break;
case 14:
mylist.clear();
break;
default:
break;
}
}
system("pause");
return 0;
}

【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)的更多相关文章

  1. C实现头插法和尾插法来构建单链表(不带头结点)

    链表的构建事实上也就是不断插入节点的过程.而节点的插入能够分为头插法和尾插法. 头插法就是在头结点后插入该节点,始终把该节点作为第一个节点.尾插法就是在链表的最后一个节点处插入元素,作为最后一个节点. ...

  2. *单链表[递归&不带头结点]

    不带头结点的单链表,递归法比较简明!(必背!) 单链表的结构: typedef struct node{ int data; struct node *next; }*List,Node; 创建第一种 ...

  3. C语言实现单链表(不带头结点)节点的插入

    对单链表进行增删改查是最主要的操作.我在上一篇博客<C语言实现链表节点的删除>实现了删除单链表中的某个节点. 这里我们要来实如今某个位置插入节点.演示样例代码上传至https://gith ...

  4. 简单约瑟夫环的循环单链表实现(C++)

    刚刚接触C++以及数据结构,今天做了第一次尝试用C++和数据结构解决问题,问题是基于约瑟夫环问题的简单版. 先来看看约瑟夫环问题的介绍: 约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3.. ...

  5. 数据结构——Java实现单链表

    一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...

  6. C代码实现非循环单链表

    C代码实现非循环单链表, 直接上代码. # include <stdio.h> # include <stdlib.h> # include <malloc.h> ...

  7. PTA 循环单链表区间删除 (15 分)

    本题要求实现带头结点的循环单链表的创建和单链表的区间删除.L是一个带头结点的循环单链表,函数ListCreate_CL用于创建一个循环单链表,函数ListDelete_CL用于删除取值大于min小于m ...

  8. C语言版本:循环单链表的实现

    SClist.h #ifndef __SCLIST_H__ #define __SCLIST_H__ #include<cstdio> #include<malloc.h> # ...

  9. c语言循环单链表

    /************************************************************************* > File Name: singleLin ...

随机推荐

  1. [Apple开发者帐户帮助]五、管理标识符(2)启用应用服务

    您可以在证书,标识符和配置文件中查看和启用App ID的服务.包含已修改的App ID的供应配置文件将变为无效.您需要重新生成使用该App ID的配置文件. 注意:要为应用程序完全配置服务,请在Xco ...

  2. python 11:range(起始索引,终止索引,步数)(默认情况下步数为1,生成从起始索引,每次增加(终止索引-起始索引)/步数,到终止索引前的数字串)

    squares = [] for value in range(1,11): #第三参数默认为1,生成从1开始,每次增加1步数,到11前的10为止的数字串 square = value ** 2 sq ...

  3. BZOJ 4195 程序自动分析

    4195: [Noi2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,-代表 ...

  4. Laravel5.1 学习笔记1, 目录结构和命名空间(待修)

    自从用 Laravel4做了个小网站,使用了数据库ORM Eloquent, 就放下了一段时间,想不到这个与Asp.net MVC 有着异曲同工之妙的框架已经出了下个版本,而且还有不小的改动,因此不得 ...

  5. PHP中的魔术方法和魔术常量

    看上去好像挺烦人,但只要通过例子测试一下,就明白了.不做测试,只是看,第二天还是不明白.当然我在抄其他人的日志,然后希望能是自己的理解就好,原文地址PHP的魔术方法和魔术敞亮简介和使用--LaraBo ...

  6. VMWare linux安装mysql 5.7.13

    1.基础环境说明 虚拟机:VMWare 操作系统:linux 数据库版本:mysql 5.7.13 社区版(别问为什么不装企业版,因为企业版要钱) 背景:虚拟机可以连上外网 下载目录: /tools/ ...

  7. js 事件冒泡、事件捕获、stopPropagation、preventDefault

    转自:http://www.jb51.net/article/42492.htm (1)冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发. IE 5.5: ...

  8. ANN:DNN结构演进History—RNN

    前言: CNN在图像处理领域的极大成功源于CNN的二维递进映射结构,通过训练多层卷积核来进行特征提取函数训练,在二维图像的稀疏表达和语义关联分析方面有天生的结构优势.而涉及时序问题的逻辑序列分析-边长 ...

  9. 【sqli-labs】 less14 POST - Double Injection - Single quotes- String -twist (POST型单引号变形双注入)

    名字和less13一样? 看了下源码对比 less13 less14 less14应该是双引号吧 出错 构造永真登陆

  10. Altova MapForce AMS/ACI/ISF自定义模板

    目前为止,我在百度上得到关于MapForce的信息少之又少,所以把自己的一些经验写下来,与大家分享. 如果要生成xml的话,就可以直接创建xml架构当作数据的目标文件. 以下是我做的AMS&A ...