数据结构——C语言实现循环双向链表

//循环单链表
#include 
#include 
#include 

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
typedef int ElemType;
typedef struct Node{
    ElemType data;
    struct Node *prior;
    struct Node *next;
}Node;

//定义LinkList *
typedef struct Node * DoubleLinkList;

//初始化
Status InitList(DoubleLinkList *L){
    // 定义头节点,循环双链表
    //头节点的数据域中存放整个链表的长度
    *L = (Node *)malloc(sizeof(Node));
    (*L)->next = (*L);//头节点next指向其本身
    (*L)->prior = (*L);//头节点的prior指向其本身
    (*L)->data = 0;//头节点中存储链表长度 
    return OK;
}
//创建单链表
//头插法
Status CreateListHead(DoubleLinkList *L){
    if(L != NULL){
        srand(5);
        for(int i = 0; i < 10; i++){
            Node *p = (Node *)malloc(sizeof(Node));
            p->next = (*L)->next;
            p->prior = (*L);
            (*L)->next->prior = p;
            (*L)->next = p;

            p->data = i + 10;
            (*L)->data++;//头节点中长度加1
        }
        return OK;
    }
    return ERROR;
}

//尾插法
Status CreateListTail(DoubleLinkList *L){
    if(L != NULL){
        srand(5);
        for(int i = 0; i < 5; i++){
            Node *p = (Node *)malloc(sizeof(Node));
            p->data = i + 20;
            p->next = (*L);
            p->prior = (*L)->prior;
            (*L)->prior->next = p;
            (*L)->prior = p;
            (*L)->data++;
        }
        return OK;
    }
    return OK;
}

//判断线性表是否为空
Status ListEmpty(DoubleLinkList L){
    //L是头指针
    if(L == NULL){
        return TRUE;
    }
    //头节点中存储的链表长度不为0
    if(L->data != 0 && L->next != L && L->prior != L){
        return FALSE;
    }
    return TRUE;
}

//返回线性表的元素个数
int ListLength(DoubleLinkList L){
    if(ListEmpty(L)){
        return 0;
    }
    DoubleLinkList p = L;//指向头节点
    int i = 0;
    while(p->next != L){
        p = p->next;
        i++;
    }
    L->data = i;//链表的长度
    return i;
}

//输出链表
void ListOutput(DoubleLinkList L){
    if(ListEmpty(L) && ListLength(L) == 0){
        printf("DoubleLinkList is Empty.\n");
        return ;
    }
    int i = 1;
    Node *p = L->next;//指首元节点
    while(p != L && i <= ListLength(L)){
        printf("%d ",p->data);
        p = p->next;
        i++;
    }
    printf("\n");
}


//清空线性表
Status ClearList(DoubleLinkList *L){
    if((*L) != NULL && !ListEmpty(*L)){
        //先断链,变成双向链表然后清空
        (*L)->prior->next = NULL;
        (*L)->prior = NULL;

        Node *p = (*L);
        while(p){
            (*L) = (*L)->next;
            free(p);
            p = (*L);
        }
       L = NULL;
    }
    return OK;
}

//获取L中第i个位置元素的值并返回
Status GetElem(DoubleLinkList L,int i,ElemType *e){
    int len  = ListLength(L);
    if(ListEmpty(L) || i > len || i < 1){
        return ERROR;
    }
    DoubleLinkList p = L;
    if(len - i > i){//从前往后找
        for(int k = 0; k < i; k++){
            p = p->next;
        }
    }else{
        for(int k = 0; k < len - i + 1; k++){
            p = p->prior;
        }
    }
    *e = p->data;
    return OK;
}

//在第i个位置上插入e
Status ListInsert(DoubleLinkList *L,int i,ElemType e){
    int len = ListLength(*L);
    //插入位置不合法
    if(L == NULL || (*L) == NULL || i > len + 1 || i < 1){
        printf("the index your insert is ERROR.\n");
        return ERROR;
    }
    Node *p = (*L);//p指向头节点
    int k = 0;
    while(k < i - 1){
        p = p->next;
        k++;
    }
    //p 指向了第i个节点的前一个节点
    Node *q = p->next;//q指向第i个节点
    Node *s = (Node *)malloc(sizeof(Node));
    s->data = e;
    s->next = q;
    s->prior = p;
    p->next = s;
    q->prior = s;

    (*L)->data++;//链表长度+1
    return OK;
}

//查找e的位置,失败则返回0
int LocateElem(DoubleLinkList L,ElemType e){
    if(ListEmpty(L)){
        return 0;
    }
    int i = 1;
    //p指向第一个节点
    Node *p = L->next;
    while(p != L && p->data != e){
        p = p->next;
        i++;
    }
    return p->data == e ? i : 0;
}

//删除L中第i个位置元素,并用e返回
Status ListDelete(DoubleLinkList *L, int i, ElemType *e){
    if(L == NULL || ListEmpty(*L) || i < 1 || i > ListLength(*L)){
        return ERROR;
    }

    Node *p = (*L);//p指向头节点
    for(int k = 0; k < i - 1; k++){
        p = p->next;
    }
    //p指向第i-1个节点
    Node *q = p->next;//q指向第i个节点
    *e = q->data;
    p->next = q->next;
    q->next->prior = p;
    free(q);
    return OK;
}


int main(){
    // 线性表的抽象数据类型
    // InitList(*L);//初始化
    // ListEmpty(L);//判断线性表是否为空
    // ClearList(*L);//清空线性表
    // GetElem(L,i,*e);//获取L中第i个位置元素的值并返回
    // LocateElem(L,e);//查找e的位置,失败则返回0
    // ListInsert(*L,i,e);//在第i个位置上插入e
    // ListDelete(*L,i,*e);//删除L中第i个位置元素,并用e返回
    // ListLength(L);//返回线性表的元素个数
    DoubleLinkList L;
    ElemType e;
    InitList(&L);
    CreateListTail(&L);
    ListOutput(L);
    printf("length = %d\n",ListLength(L));
    printf("L->data = %d\n",L->data);

    ListInsert(&L,6,100);
    ListOutput(L);

    GetElem(L,6,&e);
    printf("e = %d\n",e);

    int index = LocateElem(L,20);
    printf("the index of 20 is %d\n",index);

    ListDelete(&L,6,&e);
    printf("the element deleted is %d\n",e);
    ListOutput(L);

    ClearList(&L);
    ListOutput(L);
    return 0;
}

你可能感兴趣的:(数据结构与算法,数据结构,c语言,链表)