数据结构学习笔记-04双向循环链表

168 阅读2分钟
#include <stdio.h>
#include "stdlib.h"

#define SUCCESS 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAX_SIZE 20 /*存储空间初始分配量*/

typedef int STATUS;
typedef int Element;

//定义结点
typedef struct Node {
    Element data;
    struct Node *pre;
    struct Node *next;
}Node;

typedef struct Node * LinkList;


//创建
STATUS ListCreat(LinkList *L) {
    *L = (LinkList)malloc(sizeof(Node));
    if (*L == NULL) {
        return ERROR;
    }
    
    (*L)->next = *L;
    (*L)->pre = *L;
    
    LinkList p = *L;/*临时变量*/
    
    //新增数据: 尾插法
    for (int i = 0; i < 10; i++) {
        //1.创建1个临时的结点
        LinkList temp = (LinkList)malloc(sizeof(Node));
        temp->data = i;
        
        //2.赋值->建立双向链表关系
        //2.1建立temp 和 p之间的关系
        p->next = temp;
        temp->pre = p;
        //2.2建立头结点(*L) 和 temp之间的关系
        temp->next = (*L);
        (*L)->pre = temp;
        
        p = temp;
    }
    return SUCCESS;
}

//遍历打印
STATUS show(LinkList L) {
    if (L == NULL) {
        printf("打印的双向循环链表为空!\n\n");
        return ERROR;
    }
    
    printf("双向循环链表内容:  ");
    
    LinkList p = L->next;
    while (p != L) {
        printf("%d  ",p->data);
        p = p->next;
    }
    printf("\n\n");
    return SUCCESS;
}

//增:插入位置超过链表长度时,就插入尾部
STATUS ListInsert(LinkList *L,int index,Element data) {
    //1.
    if (*L == NULL) {
        return ERROR;
    }
    
    //2.
    LinkList p = *L;/*临时变量*/
    int i = 1;
    
    //3.找到插入前一个位置上的节点
    while (i < index && p->next != *L) {
        p = p->next;
        i++;
    }
    
    //4.如果i > index,则返回 error
    if (i > index) {
        return ERROR;
    }
    
    //5.创建新结点temp
    LinkList temp = (LinkList)malloc(sizeof(Node));
    temp->data = data;
    
    //6.构造双向循环链表关系
    //6.1 temp和p的关系
    temp->pre = p;
    temp->next = p->next;//这句话要先于下一句,不然会丢失p->next
    p->next = temp;
    
    //6.2如果temp不是最后一个节点
    if (temp->next != *L) {
        //temp节点的下一个结点的前驱为temp 结点
        temp->next->pre = temp;
    } else {
        (*L)->pre = temp;
    }
    
    return SUCCESS;
}

//删
STATUS ListDelete(LinkList *L,int index,Element *data) {
    if (*L == NULL) {
        return ERROR;
    }
    
    int i = 1;
    LinkList p = (*L)->next;
    
    //如果删除到只剩下首元结点了,则直接将*L置空;
    if (p->next == *L) {
        free(*L);
        (*L) = NULL;
        return SUCCESS;
    }
    
    //1.找到要删除的节点
    while (i < index && p != *L) {
        p = p->next;
        i++;
    }
    
    //2.没有找到对应位置(超过链表长度)
    if (i != index) {
        return ERROR;
    }
    
    //3.给目标赋值
    *data = p->data;
    
    //4.建立双向链表关系
    p->pre->next = p->next;
    p->next->pre = p->pre;
    
    //5.删除节点
    free(p);
    return SUCCESS;
}



int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
        
    LinkList L;
    STATUS iStatus;
    
    iStatus = ListCreat(&L);
    show(L);
    
    ListInsert(&L, 1, 99);
    show(L);
    ListInsert(&L, 29, 88);
    show(L);
    
    Element data;
    ListDelete(&L, 2, &data);
    printf("位置%d上被删除的是%d\n",2,data);
    
    Element data1;
    ListDelete(&L, 20, &data1);
    printf("位置%d上被删除的是%d\n",20,data1);
    
    return 0;
}