循环单链表的简单实现(C语言)

本文介绍了如何使用C语言实现循环单链表,包括其插入(前插、后插、头插、尾插、按位插入)、删除(结点后删、按位删除、销毁表)、查找(按位查找、按值查找)等操作,以及定义、初始化、求表长、输出表、表判空和判断表尾的方法。
摘要由CSDN通过智能技术生成

简述

循环单链表和单链表的不同之处在于——单链表的表尾指向空,而循环单链表的表尾指向头部第一个结点。因此,他们的边界处理会有些不同。循环单链表的好处在于——给出任一结点都能找到链表中的所有结点。而单链表只能找到该结点后面的结点,对于该节点前面的结点单链表是完全未知的。

插入

前插结点

// 前插结点
bool InsertpriorNode(CLNode *p, ElemType e){
   
    if(p == NULL)   return false; // 数据合法性判断
    CLNode *s = (CLNode*)malloc(sizeof(CLNode));    // p为当前结点,s为欲插结点
    if(s == NULL)   return false;   // 内存不足,分配失败
    // 偷梁换柱法 将p存入s,再令p存入新数据.本质上还是后插
    s->data = p->data;  // p数据域存入s
    s->next = p->next;  // s下一结点指向p原后继结点
    p->next = s;        // p下一结点指向s
    p->data = e;        // p存入插入的数据
    return true;
}

后插结点

// 后插结点
bool InsertNextNode(CLNode *p, ElemType e){
   
    if(p == NULL)   return false;       // 数据合法性判断
    CLNode *s = (CLNode*)malloc(sizeof(CLNode));
    if((s) == NULL) return false;   // 内存不足,分配失败
    s->data = e;        // 存入数据域
    s->next = p->next;  // s联结p原后继
    p->next = s;        // p联结s
    return true;
}

头插法

// 头插法
CLinkList List_HeadInsert(CLinkList L){
   
   ElemType e;
   scanf("%d", &e);
   while(e != 9999){
   
       // 第一个结点要特殊处理
        if(L->next == L){
      // 链表为空则创建一个新结点
            CLNode *p = (CLNode*)malloc(sizeof(CLNode));
            L->next = p;    // 令新结点成为头结点的后继结点
            p->next = L;
            p->data = e;
       }else{
   
            InsertpriorNode(L->next, e);    // 进行结点后插操作
       }      
       scanf("%d", &e);
   } 
   return L;
}

尾插法

// 尾插法
CLinkList List_TailInsert(CLinkList L){
      
    ElemType e;
    scanf("%d", &e);
    while(e != 9999){
     
        CLNode *p = (CLNode*)malloc(sizeof(CLNode));
        p = L;
        while(p->next != L){
       // 第一个结点进行特殊处理
            if(L->next == L){
      // 头结点为空则创建一个新结点
            CLNode *p = (CLNode*)malloc(sizeof(CLNode));
            L->next = p;    // L的下一结点指向p
            p->next = L;    // p的下一结点指向L
            p->data = e;    // p存入数据
        }
            p = p->next;        // 移到下一个结点
        }
        InsertNextNode(p, e);   // 调用后插结点函数进行后插操作
        scanf("%d", &e);
    }
    return L;
}

按位插入

// 按位插入
bool ListInsert(CLinkList *L, int pos, ElemType e){
   
    CLNode *p = *L;
    int i = 0;
    for(i; i < pos-1; i++){
            // 定位到欲插入位序的前继结点
        p = p->next;
    }
    if(InsertNextNode(p, e)){
      // 调用后插结点函数进行后插操作并判断操作是否成功
        return true;
    }else false;         
}

删除

结点后删

// 结点后删
bool DeleteNode(CLNode *p){
        // 删除p结点的后继结点
    if(p == NULL) return false; // 数据非法性判断
    CLNode *s = p->next;        // s为p的后继结点
    p->next = s->next;          // p指向s的后继结点
    free(s
  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值