数据结构——C语言实现单向循环链表

//循环单链表
#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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值