純C語言實現循環雙向鏈表建立,插入和刪除

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;

typedef struct DLNode{
    ElemType data;
    struct DLNode *next;
    struct DLNode *prior;
}DLNode;

DLNode *InitList(DLNode *DL);//初始化
int ListEmpty(DLNode *DL);//判空
int ListLength(DLNode *DL);//返回鏈表長度
int ListInsert(DLNode *DL, int i, ElemType e);//插入元素
int ListDelete(DLNode *DL, int i);//刪除第i個元素
void TraverseList(DLNode *DL);//遍歷線性表

//初始化
DLNode* InitList(DLNode *DL){
    int x;
    DLNode *p = NULL;
    DLNode *r = NULL;

    DL = (DLNode *)malloc(sizeof(DLNode));
    DL->next = DL;
    DL->prior = DL;
    r = DL;

    printf("輸入直到-1爲止\n");
    while(1){
        scanf("%d", &x);
        if(x == -1){
            printf("初始化成功\n");
            break;
        }
        p = (DLNode *)malloc(sizeof(DLNode));
        if(p){
            p->data = x;
            p->prior = r;
            p->next = DL;
            r->next = p;
            DL->prior = p;
            r = p;
        }else{
            printf("空間不足初始化失敗\n");
            return NULL;
        }

    }
    return DL;

}

//判空
int ListEmpty(DLNode *DL){
    return (DL->next == DL);
}

//插入元素
int ListInsert(DLNode *DL, int i, ElemType e){
    if(i>ListLength(DL)+1 || i<=0){
        printf("插入位置有誤,插入失敗\n");
        return 0;
    }
    DLNode *p = DL;
    int j = 0;
    while(j<i){
        p = p->next;
        j++;
    }

    DLNode *nDLNode = (DLNode *)malloc(sizeof(DLNode));
    nDLNode->data = e;
    nDLNode->prior = p->prior;
    p->prior->next = nDLNode;
    p->prior = nDLNode;
    nDLNode->next = p;
    printf("插入成功\n");
    return 1;
}

//刪除第i個元素
int ListDelete(DLNode *DL, int i){
    if(i>ListLength(DL) || i<=0){
        printf("刪除位置有誤,插入失敗\n");
        return 0;
    }
    DLNode *p = DL;
    int j = 0;
    while(j<i){
        p = p->next;
        j++;
    }
    p->prior->next = p->next;
    p->next->prior = p->prior;

    free(p);
    printf("刪除成功\n");
    return 1;
}


//返回鏈表長度
int ListLength(DLNode *DL){
    int len = 0;
    if(ListEmpty(DL)) return 0;
    DLNode *p = DL->next;
    while(p->data!=DL->data){
        len++;
        p = p->next;
    }
    return len;
}

//遍歷線性表
void TraverseList(DLNode *DL){
    if(ListEmpty(DL)){
        printf("空鏈表");
    }
    DLNode *p = DL->next;
    //終止循環遍歷
    while(p->data != DL->data){
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}


int main(){
    ElemType e = NULL;
    DLNode *DL = NULL;

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

//    //等價測試
//    DLNode *d = DL->next->next;
//    if(d->next->prior == d->prior->next){
//        printf("d->next->prior == d->prior->next\n");
//    }
//    if(d->next->prior == d){
//        printf("d->next->prior == d\n");
//    }
//    if(d == d->prior->next){
//        printf("d == d->prior->next\n");
//    }

    //遍歷測試
    TraverseList(DL);
//
//    printf("雙向循環鏈表長度爲%d\n",ListLength(DL));


    //插入元素測試
    printf("第3個位置插入999\n");
    ListInsert(DL, 3, 999);
    TraverseList(DL);
//-----------------------------------------------------
    //非法操做?循環雙向鏈表插入一個巨大的位置是否合法?
    //和老師討論完,算不合法
    printf("第567位置插入999\n");
    ListInsert(DL, 567, 999);
    TraverseList(DL);
//------------------------------------------------------
    //刪除元素測試
//    printf("刪除第1個位置\n");
//    ListDelete(DL, 1);
//    TraverseList(DL);
//------------------------------------------------------
    //非法操做?同上
    //新問題,1,2,3,4,-1,刪除第5個是頭節點。
    //和老師討論完,算不合法
//    printf("刪除第55位置\n");
//    ListDelete(DL, 55);
//    TraverseList(DL);
//------------------------------------------------------


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