zoukankan      html  css  js  c++  java
  • 纯C语言实现线性链表

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef int ElemType;
    
    typedef struct LNode{
        ElemType data;
        struct LNode *next;
    }LNode;
    
    LNode *InitList(LNode *L);//初始化
    LNode *DestroyList(LNode *L);//销毁
    void ClearList(LNode *L);//清空列表
    int ListEmpty(LNode *L);//判空
    int ListLength(LNode *L);//返回链表长度
    int GetElem(LNode *L, int i, ElemType *e);//获取第i个元素
    LNode* LocateElem(LNode *L, ElemType e);//定位值为e的位置
    ElemType PriorElem(LNode *L, ElemType cur_e);//查找前驱
    ElemType NextElem(LNode *L, ElemType cur_e);//查找后继
    int ListInsert(LNode *L, int i, ElemType e);//插入元素
    int ListDelete(LNode *L, int i);//删除第i个元素
    void TraverseList(LNode *L);//遍历线性表
    
    //初始化
    LNode *InitList(LNode *L){
        int x;
        LNode *p = NULL;//记录前一个节点
        LNode *q = NULL;//记录后一个节点
    
        L = (LNode *)malloc(sizeof(LNode));
        L->next = NULL;
        p = L;
    
        printf("输入直到-1为止
    ");
        while(1){
            scanf("%d", &x);
            if(x == -1) {
                printf("初始化成功
    ");
                break;
            }
            //初始化并赋值
            q = (LNode *)malloc(sizeof(LNode));
            if(q){
                q->data = x;
                q->next = NULL;
                //和前一个节点连接
                p->next = q;
                //遍历下去
                p = p->next;
            }else{
                printf("空间不足,初始化失败
    ");
                return NULL;
            }
    
        }
        return L;
    }
    
    //销毁
    LNode *DestroyList(LNode *L){
        LNode *p = L->next;//记录前一个元素
        LNode *q = p->next;//记录后一个元素
        while(q){
            free(p);
            p = q;
            q = q->next;
        }
        free(p);
        free(L);
        printf("销毁成功
    ");
        return NULL;
    }
    
    //清空列表
    void ClearList(LNode *L){
        LNode *p = L->next;
        while(p){
            p->data = 0;
            p = p->next;
        }
        printf("清空成功
    ");
    }
    
    //判空,1为空,0不为空
    int ListEmpty(LNode *L){
        return L->next == NULL;
    }
    
    //返回链表长度,返回链表长度
    int ListLength(LNode *L){
        int len = 0;
        if(ListEmpty(L)) return 0;
        LNode *p = L->next;
        while(p){
            len++;
            p = p->next;
        }
        return len;
    }
    
    //获取第i个元素,将值保存到参数e中,返回是否获取的状态
    int GetElem(LNode *L, int i, ElemType *e){
        if(ListEmpty(L)){
            printf("空链表
    ");
            return 0;
        }
        LNode *p = L->next;
        int j = 1;
        while(p && j<i){
            p = p->next;
            j++;
        }
        //i值不合法 >length 或者 <=0
        if(!p||j>i) {
            printf("获取元素的位置%d不合法
    ", i);
            return 0;
        }
        *e = p->data;
        printf("第%d个元素是%d
    ",i,*e);
        return 1;
    }
    
    //定位值为e的位置,返回指针指向节点
    LNode* LocateElem(LNode *L, ElemType e){
        LNode *p = L->next;
        while(p && p->data!=e){
            p = p->next;
        }
        return p;
    }
    
    //查找值为e的前驱,返回前驱元素
    ElemType PriorElem(LNode *L, ElemType cur_e){
        LNode *p = L->next;
        int idx = 1;
        while(p && p->data!=cur_e){
            p = p->next;
            idx++;
        }
        if(!p || idx>ListLength(L)){
            printf("查不到此元素
    ");
            return cur_e;
        }
        ElemType e = NULL;
        GetElem(L, idx-1, &e);
        if(e){
            printf("%d的前驱是%d
    ", cur_e, e);
        }else{
            printf("%d无前驱或获取元素的位置不合法
    ",cur_e);
        }
        return e;
    }
    
    //查找值为e的后继
    ElemType NextElem(LNode *L, ElemType cur_e){
        LNode *Locate = LocateElem(L, cur_e);
        if(Locate && Locate->next){
            printf("%d的后继是%d
    ", cur_e, Locate->next->data);
        }else{
            printf("%d无后继或获取元素的位置不合法
    ",cur_e);
        }
        return Locate->next->data;
    }
    
    //插入元素
    int ListInsert(LNode *L, int i, ElemType e){
        LNode *p = L;
        int j = 0;
        //指向要插入的前一个节点
        while(p && (j<i-1)){
            p = p->next;
            j++;
        }
        if(!p || j>i-1){
            printf("插入失败
    ");
            return 0;}
        LNode *nLNode = (LNode *)malloc(sizeof(LNode));
        nLNode->data = e;
        nLNode->next = p->next;
        p->next = nLNode;
        printf("插入成功
    ");
        return 1;
    }
    
    //删除第i个元素
    int ListDelete(LNode *L, int i){
        LNode *p = L;
        LNode *q = NULL;
        int j = 0;
        //指向要删除的前一个节点
        while((p->next && (j<i-1))){
            p = p->next;
            j++;
        }
        if(!(p->next) || (j>i-1)){
            printf("删除失败
    ");
            return 0;
        }
        q = p->next; //q指向即将删除的节点
        p->next = q->next;
        free(q);
        printf("删除成功
    ");
        return 1;
    }
    
    //遍历线性表
    void TraverseList(LNode *L){
        if(ListEmpty(L)){
            printf("空链表");
            return;
        }
        LNode *p = L->next;
        while(p){
            printf("%d ", p->data);
            p = p->next;
        }
        printf("
    ");
    }
    
    
    int main(){
        ElemType e = NULL;
        LNode *L = NULL;
        LNode *Locate = NULL;//用于定位查找到的节点
    
        //初始化测试
        L = InitList(L);
    
        //遍历测试
        TraverseList(L);
    
    //    //长度测试
    //    printf("线性表长度为%d
    ", ListLength(L));
    
    //    //获取第i个元素测试
    //    GetElem(L, 1, &e);
    //    //非法操作
    //    GetElem(L, 999, &e);
    
    //    //获取值为2的元素位置测试
    //    Locate = LocateElem(L, 2);
    //    if(Locate){
    //        printf("值为2的元素被Locate指向
    ");
    //    }else{
    //        printf("没有值为2的元素被指向
    ");
    //    }
    
    //    //获取元素值为2的前驱测试
    //    PriorElem(L, 2);
    //    //非法操作
    //    GetElem(L, 1, &e);
    //    PriorElem(L, e);
    
    //    //获取元素值为2的后继测试
    //    NextElem(L, 2);
    //    //非法操作
    //    GetElem(L, ListLength(L), &e);
    //    NextElem(L, e);
    
    //    //插入元素测试
    //    printf("第3个位置插入999
    ");
    //    ListInsert(L, 1, 999);
    //    TraverseList(L);
    //    //非法操作
    //    printf("第999位置插入999
    ");
    //    ListInsert(L, 999, 999);
    //    TraverseList(L);
    
    //    //删除元素测试
    //    printf("删除第3个位置
    ");
    //    ListDelete(L, 3);
    //    TraverseList(L);
    //    //非法操作
    //    printf("删除第999位置
    ");
    //    ListDelete(L, 999);
    //    TraverseList(L);
    
    //    //清空链表测试
    //    ClearList(L);
    //    TraverseList(L);
    
        //销毁测试
        L = DestroyList(L);
        TraverseList(L);
        printf("线性表长度为%d
    ", ListLength(L));
    
    }
    作者:PowerZZJ
    本博客文章大多为原创,转载请请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Golang网络编程-套接字(socket)篇
    Golang并发编程-传统的同步工具"锁"实战篇
    Golang并发编程-select实战篇
    Golang并发编程-channel实战篇
    Golang并发编程-Go程(Goroutine)实战篇
    Jenkins实现简单流程部署代码
    Jenkins权限管理
    Jenkins插件管理篇
    Jenkins部署实战案例
    Golang常见的字符串函数操作实战篇
  • 原文地址:https://www.cnblogs.com/powerzzjcode/p/10889101.html
Copyright © 2011-2022 走看看