//循环单链表
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct Node{
ElemType data;
struct Node *next;
}Node;
//定义LinkList *
typedef struct Node * CircularLinkList;
//初始化
Status InitList(CircularLinkList *L){
// 定义头节点,循环单链表,并且定义尾指针
//头节点的数据域中存放整个链表的长度
*L = (Node *)malloc(sizeof(Node));
(*L)->next = (*L);//头节点next指向其本身
(*L)->next->data = 0;
return OK;
}
//创建单链表
//头插法
Status CreateListHead(CircularLinkList *L){
if(L != NULL){
CircularLinkList tail;
srand(5);
for(int i = 0; i < 10; i++){
Node *p = (Node *)malloc(sizeof(Node));
p->next = (*L)->next;
p->data = i + 12;
(*L)->next = p;
(*L)->data++;//头节点中长度加1
if(i == 0){
tail = p;
}
}
(*L) = tail;
return OK;
}
return ERROR;
}
//尾插法
Status CreateListTail(CircularLinkList *L){
if(L != NULL){
srand(5);
Node *tail = (*L);
for(int i = 0; i < 10; i++){
Node *p = (Node *)malloc(sizeof(Node));
p->next = (*L);
p->data = i + 23;
tail->next = p;
tail = p;//tail移到链表尾部
(*L)->data++;
}
(*L) = tail;//L指向链表尾部
return OK;
}
return OK;
}
//判断线性表是否为空
Status ListEmpty(CircularLinkList L){
//L是尾指针
if(L == NULL){
return TRUE;
}
//头节点中存储的链表长度不为0
if(L->next->data != 0 && L->next != L){
return FALSE;
}
return TRUE;
}
//返回线性表的元素个数
int ListLength(CircularLinkList L){
if(ListEmpty(L)){
return 0;
}
CircularLinkList p = L->next->next;//指向首元节点
int i = 0;
while(p != L->next){
i++;
p = p->next;
}
L->next->data = i;//链表的长度
return i;
}
//输出链表
void ListOutput(CircularLinkList L){
if(ListEmpty(L) && ListLength(L) == 0){
printf("CircularLinkList is Empty.\n");
return ;
}
int i = 1;
Node *p = L->next->next;//指向首元节点
while(p != L->next && i <= ListLength(L)){
printf("%d ",p->data);
p = p->next;
i++;
}
printf("\n");
}
//清空线性表
Status ClearList(CircularLinkList *L){
if((*L) != NULL && !ListEmpty(*L)){
Node *p = (*L)->next;
Node *q = p->next;
while(p != (*L)){
q = q->next;
free(p);
p = q;
}
free(*L);
*L = NULL;
L = NULL;
}
return OK;
}
//获取L中第i个位置元素的值并返回
Status GetElem(CircularLinkList L,int i,ElemType *e){
if(ListEmpty(L) || i > ListLength(L)){
return ERROR;
}
CircularLinkList p = L->next;
for(int k = 1; k <= i; k++){
p = p->next;
}
*e = p->data;
return OK;
}
//在第i个位置上插入e
Status ListInsert(CircularLinkList *L,int i,ElemType e){
int len = ListLength(*L);
//插入位置不合法
if(L == NULL || (*L) == NULL || i > len + 1 || i < 1){
return ERROR;
}
Node *p = (*L)->next;//p指向头节点
int k = 0;
while(k < i - 1){
p = p->next;
k++;
}
//p 指向了第i个节点的前一个节点
Node *q = p->next;//q指向第i个节点
Node *s = (Node *)malloc(sizeof(Node));
s->data = e;
s->next = q;
p->next = s;
//如果在最后一个插入则尾指针后移
if(i == len + 1){
(*L) = (*L)->next;
}
(*L)->next->data++;//链表长度+1
return OK;
}
//查找e的位置,失败则返回0
int LocateElem(CircularLinkList L,ElemType e){
if(ListEmpty(L)){
return 0;
}
int i = 1;
//p指向第一个节点
Node *p = L->next->next;//头节点
while(p != L && p->data != e){
p = p->next;
i++;
}
return p->data == e ? i : 0;
}
//删除L中第i个位置元素,并用e返回
Status ListDelete(CircularLinkList *L, int i, ElemType *e){
if(L == NULL || ListEmpty(*L) || i < 1 || i > ListLength(*L)){
return ERROR;
}
if(i == ListLength(*L)){
Node *q = (*L);//尾指针
*e = q->data;
while(q->next != (*L)){
q = q->next;
}
q->next = (*L)->next;
Node *t = (*L);
(*L) = q;
free(t);
}else{
Node *p = (*L)->next;//p指向头节点
for(int k = 0; k < i - 1; k++){
p = p->next;
}
//p指向第i-1个节点
Node *q = p->next;//q指向第i个节点
*e = q->data;
p->next = q->next;
free(q);
}
return OK;
}
int main(){
// 线性表的抽象数据类型
// InitList(*L);//初始化
// ListEmpty(L);//判断线性表是否为空
// ClearList(*L);//清空线性表
// GetElem(L,i,*e);//获取L中第i个位置元素的值并返回
// LocateElem(L,e);//查找e的位置,失败则返回0
// ListInsert(*L,i,e);//在第i个位置上插入e
// ListDelete(*L,i,*e);//删除L中第i个位置元素,并用e返回
// ListLength(L);//返回线性表的元素个数
CircularLinkList L;
ElemType e;
InitList(&L);
CreateListTail(&L);
ListOutput(L);
printf("length = %d\n",ListLength(L));
ListInsert(&L,11,100);
ListOutput(L);
GetElem(L,11,&e);
printf("e = %d\n",e);
int index = LocateElem(L,100);
printf("the index of 100 is %d\n",index);
ListDelete(&L,1,&e);
printf("the element deleted is %d\n",e);
ListOutput(L);
ClearList(&L);
ListOutput(L);
return 0;
}
数据结构——C语言实现单向循环链表
于 2023-08-30 22:30:39 首次发布