纯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);
//------------------------------------------------------


}

 

posted @ 2019-05-20 21:11  PowerZZJ  阅读(1577)  评论(0编辑  收藏  举报