純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爲止\n");
    while(1){
        scanf("%d", &x);
        if(x == -1) {
            printf("初始化成功\n");
            break;
        }
        //初始化並賦值
        q = (LNode *)malloc(sizeof(LNode));
        if(q){
            q->data = x;
            q->next = NULL;
            //和前一個節點鏈接
            p->next = q;
            //遍歷下去
            p = p->next;
        }else{
            printf("空間不足,初始化失敗\n");
            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("銷燬成功\n");
    return NULL;
}

//清空列表
void ClearList(LNode *L){
    LNode *p = L->next;
    while(p){
        p->data = 0;
        p = p->next;
    }
    printf("清空成功\n");
}

//判空,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("空鏈表\n");
        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不合法\n", i);
        return 0;
    }
    *e = p->data;
    printf("第%d個元素是%d\n",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("查不到此元素\n");
        return cur_e;
    }
    ElemType e = NULL;
    GetElem(L, idx-1, &e);
    if(e){
        printf("%d的前驅是%d\n", cur_e, e);
    }else{
        printf("%d無前驅或獲取元素的位置不合法\n",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\n", cur_e, Locate->next->data);
    }else{
        printf("%d無後繼或獲取元素的位置不合法\n",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("插入失敗\n");
        return 0;}
    LNode *nLNode = (LNode *)malloc(sizeof(LNode));
    nLNode->data = e;
    nLNode->next = p->next;
    p->next = nLNode;
    printf("插入成功\n");
    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("刪除失敗\n");
        return 0;
    }
    q = p->next; //q指向即將刪除的節點
    p->next = q->next;
    free(q);
    printf("刪除成功\n");
    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("\n");
}


int main(){
    ElemType e = NULL;
    LNode *L = NULL;
    LNode *Locate = NULL;//用於定位查找到的節點

    //初始化測試
    L = InitList(L);

    //遍歷測試
    TraverseList(L);

//    //長度測試
//    printf("線性表長度爲%d\n", ListLength(L));

//    //獲取第i個元素測試
//    GetElem(L, 1, &e);
//    //非法操做
//    GetElem(L, 999, &e);

//    //獲取值爲2的元素位置測試
//    Locate = LocateElem(L, 2);
//    if(Locate){
//        printf("值爲2的元素被Locate指向\n");
//    }else{
//        printf("沒有值爲2的元素被指向\n");
//    }

//    //獲取元素值爲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\n");
//    ListInsert(L, 1, 999);
//    TraverseList(L);
//    //非法操做
//    printf("第999位置插入999\n");
//    ListInsert(L, 999, 999);
//    TraverseList(L);

//    //刪除元素測試
//    printf("刪除第3個位置\n");
//    ListDelete(L, 3);
//    TraverseList(L);
//    //非法操做
//    printf("刪除第999位置\n");
//    ListDelete(L, 999);
//    TraverseList(L);

//    //清空鏈表測試
//    ClearList(L);
//    TraverseList(L);

    //銷燬測試
    L = DestroyList(L);
    TraverseList(L);
    printf("線性表長度爲%d\n", ListLength(L));

}
相關文章
相關標籤/搜索