您的位置:首页 > 理论基础 > 数据结构算法

《数据结构》进行曲--带头结点的单循环链表的基本操作

2016-02-26 22:31 561 查看
单循环链表
循环链表的特点是最后一个元素的指针域指向头结点。



因此对于循环链表的初始化(设表的头结点是L, 不再是L->next=NULL,而是L->next=L。循环链表为空时,头结点的下一个结点依然是头结点本身。因此但虚幻链表的初始化如下:(数据类型设为int)

//初始化
int InitList(LinkList &L){
L=new LNode;
L->next=L;//非循环链表的初始化是头指针的指针域置空 L->next=NULL
return 1;
}


所以根据循环链表的特点,判断循环链表是否为空时,只需判断头结点的下一个结点是否是头结点即可:

//判断链表是否为空
int ListEmpty(LinkList L){
if(L->next==L){
return 1;//空
}else{
return 0;//非空
}
}


从头检查每一个结点,若当前结点不是头结点,则链表长度加1,由此可计算链表的长度:

//获取链表长度
int ListLength(LinkList L){
int length=0;
struct LNode *p;
p=L->next;
while(p!=L){//当p不是头结点时,链表长度加1
p=p->next;
++length;
}
return length;
}


//遍历链表
void TraveList(LinkList L){
struct LNode *p;
p=L->next;
printf("遍历链表:\n");
while(p!=L){//当p不是头结点时,输出元素值
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}


使用头插法和尾插法创建单循环链表的方法和创建一般单链表的操作一样,区别在于建立空链表的语句不同。一般单链表是L->next=NULL,而单循环链表是L->next=L。

//头插法创建单循环链表
void CreateList1(LinkList &L,int n){
//创建长度为n的单循环链表
L=new LNode;
L->next=L;
printf("请输入链表元素值:\n");
for(int i=n;i>0;--i){
printf("请输入第%d个元素的值:",i);
struct LNode *p;
p=new LNode;//生成新结点
scanf("%d",&p->data);
p->next=L->next;;
L->next=p;
}
}


//尾插法创建单循环链表
void CreateList2(LinkList &L,int n){
L=new LNode;
L->next=L;
struct LNode *r;
r=L;
for(int i=0;i<n;i++){
printf("请输入第%d个元素的值:",i+1);
struct LNode *p;
p=new LNode;
scanf("%d",&p->data);
p->next=L;
r->next=p;
r=p;
}
}


单循环链表的删除操作和一般单链表的操作时一样的。要注意的是单循环链表的插入操作:

//单循环链表的删除操作
int ListDelete(LinkList &L,int location,int &e){
//删除L中location位置的元素,并用e返回其值
struct LNode *p;
p=L;
int j=0;
while(p->next!=L&&j<location-1){
p=p->next;
++j;
}
if(p==L||j>location-1){
return 0;
}
struct LNode *q;
q=new LNode;
q=p->next;
p->next=q->next;
e=q->data;
delete q;
return 1;
}


//单循环链表的插入操作
int ListInsert(LinkList &L,int location,int &e){
//在L的location位置插入元素e
struct LNode *p;
p=L;
int j=0;
while(p->next!=L&&j<location-1){
<span style="color:#ff0000;">//注意:由于p初始时指向头结点,所以循环的条件是 p->next!=L
//而不是 p!=L
p=p->next;
++j;
}
if(p==L||j>location-1){
return 0;
}
struct LNode *s;
s=new LNode;
s->data=e;
s->next=p->next;
p->next=s;
return 1;
}


单循环链表的基本操作的实现:

#include<stdio.h>
#include<iostream>
using namespace std;

#define MAX 100

//存储结构
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;

//初始化 int InitList(LinkList &L){ L=new LNode; L->next=L;//非循环链表的初始化是头指针的指针域置空 L->next=NULL return 1; }

//判断链表是否为空 int ListEmpty(LinkList L){ if(L->next==L){ return 1;//空 }else{ return 0;//非空 } }

//获取链表长度
int ListLength(LinkList L){
int length=0;
struct LNode *p;
p=L->next;
while(p!=L){//当p不是头结点时,链表长度加1
p=p->next;
++length;
}
return length;
}

//遍历链表
void TraveList(LinkList L){
struct LNode *p;
p=L->next;
printf("遍历链表:\n");
while(p!=L){//当p不是头结点时,输出元素值
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}

//头插法创建单循环链表
void CreateList1(LinkList &L,int n){
//创建长度为n的单循环链表
L=new LNode;
L->next=L;
printf("请输入链表元素值:\n");
for(int i=n;i>0;--i){
printf("请输入第%d个元素的值:",i);
struct LNode *p;
p=new LNode;//生成新结点
scanf("%d",&p->data);
p->next=L->next;;
L->next=p;
}
}

//尾插法创建单循环链表
void CreateList2(LinkList &L,int n){
L=new LNode;
L->next=L;
struct LNode *r;
r=L;
for(int i=0;i<n;i++){
printf("请输入第%d个元素的值:",i+1);
struct LNode *p;
p=new LNode;
scanf("%d",&p->data);
p->next=L;
r->next=p;
r=p;
}
}

//单循环链表的插入操作
int ListInsert(LinkList &L,int location,int &e){
//在L的location位置插入元素e
struct LNode *p;
p=L;
int j=0;
while(p->next!=L&&j<location-1){
//注意:由于p初始时指向头结点,所以训话的条件是 p->next!=L
//而不是 p!=L
p=p->next;
++j;
}
if(p==L||j>location-1){
return 0;
}
struct LNode *s;
s=new LNode;
s->data=e;
s->next=p->next;
p->next=s;
return 1;
}

//单循环链表的删除操作
int ListDelete(LinkList &L,int location,int &e){
//删除L中location位置的元素,并用e返回其值
struct LNode *p;
p=L;
int j=0;
while(p->next!=L&&j<location-1){
p=p->next;
++j;
}
if(p==L||j>location-1){
return 0;
}
struct LNode *q;
q=new LNode;
q=p->next;
p->next=q->next;
e=q->data;
delete q;
return 1;
}
int main(){
LinkList L;

if(InitList(L)){
printf("初始化成功!\n");
}else{
printf("初始化失败!\n");
}

if(ListEmpty(L)){
printf("当前链表为空.\n");
}else{
printf("链表非空.\n");
}

printf("请输入链表长度:");
int n;
scanf("%d",&n);
//CreateList1(L,n);
CreateList2(L,n);

if(ListEmpty(L)){
printf("当前链表为空.\n");
}else{
printf("链表非空.\n");
}

printf("当前链表长度是:%d\n",ListLength(L));
TraveList(L);

printf("请输入插入位置和值:\n");
int location,e;
scanf("%d%d",&location,&e);
if(ListInsert(L,location,e)){
printf("插入成功\n");
}else{
printf("插入失败\n");
}
TraveList(L);

printf("请输入删除元素的位置:\n");
int e1,location1;
scanf("%d",&location1);
if(ListDelete(L,location1,e1)){
printf("删除成功\n");
printf("删除的元素值为:%d\n",e1);
}else{
printf("删除失败\n");
}
TraveList(L);
}




有错误敬请读者指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: