线性表-双向循环链表

328 阅读3分钟
  • 双向循环链表概念

    1. 概念
      与双向链表的不同在于循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环,即:双向循环链表的尾结点的next会指向头结点,头结点的prior会指向尾结点
    2. 结点图解
    3. 链表图解(含有头结点的链表)
  • 初始化

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

typedef int Status;
typedef int ElemType;

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

typedef struct Node *LinkList;

//双向链表操作(含有头结点)(也可以不设置头结点,但是在插入的时候就需要多判断插入的位置是不是1  是的话需要修改首指针的指向)
//1.创建一个新的节点
//2.找到尾节点
//3.新节点的next指向头结点
//4.新节点的prior指向尾结点
//5.尾节点的next 指向新节点
//6.头结点的prior指向新节点
Status createLinkList(LinkList *L){
    int number;
    LinkList temp = NULL;
    LinkList target = NULL;
    if((*L) == NULL){
        *L = (LinkList)malloc(sizeof(Node));
        if(L == NULL) exit(0);
        (*L)->next = (*L);
        (*L)->prior = (*L);
    }
    printf("可输入一个数值用于插入懂啊链表,输入0跳出循环\n");
    //向链表中插入数据
    while(1){
        scanf("%d",&number);
        if(number == 0) break;
        temp = (LinkList)malloc(sizeof(Node));
        if(temp == NULL) exit(0);
        for(target = *L; target->next != *L; target = target->next);
        temp->data = number;
        temp->prior = target;
        temp->next = target->next;
        target->next->prior = temp;
        target->next = temp;
    }
    
    return OK;
}
  • 插入

//插入元素
//1.找到插入位置的前驱节点target
//2.创建一个新节点temp并赋值
//3.temp->next指向target->next
//4.target->next->prior指向temp
//5.target->next指向temp
//6.temp->prior 指向target
Status insert(LinkList *L,int item, int place){
//    printf("插入的元素是%d",item);
    if(*L == NULL) return ERROR;
    if(place < 1) return ERROR;
    LinkList temp = NULL;
    LinkList target = (*L);
    int i;
    for (i = 1; i < place && target->next != (*L); i++,target = target->next);
    if(i != place) return ERROR;
    
    
    temp = (LinkList)malloc(sizeof(LinkList));
    if(temp == NULL) exit(0);
    temp->data = item;
    temp->next = target->next;
    temp->prior = target;
    target->next->prior = temp;
    target->next = temp;
    return OK;
}
  • 删除

//删除元素
//1.找到删除位置的前驱节点target
//2.创建temp指向target->next
//3.target->next指向temp->next
//4.temp->next->prior指向target
//4.free(temp)
Status delete(LinkList *L,int place){
    if(*L == NULL) return ERROR;
    if(place < 1) return ERROR;
    LinkList target = (*L);
    LinkList temp = NULL;
    int i;
    for (i = 1; i < place && target->next != (*L); i++,target = target->next);
    if(i != place) return ERROR;
    if(target->next == *L) return ERROR;
    temp = target->next;
    temp->next->prior = target;
    target->next = temp->next;
    free(temp);
    return OK;
}
  • 修改、查找、遍历

//修改内容
Status modify(LinkList *L, int place, ElemType e){
    if(place < 1) return ERROR;
    if(!*L) return ERROR;
    LinkList temp = NULL;
    int i = 1;
    for (temp = (*L)->next; temp != *L; temp = temp->next) {
        if(i == place){
            temp->data = e;
            return TRUE;
        }
        i++;
    }
    return FALSE;
}
//查找内容
Status getElem(LinkList L, int place, ElemType *e){
    LinkList temp = NULL;
    int i = 1;
    for (temp = L->next; temp != L; temp = temp->next) {
        if(i == place){
            (*e) = temp->data;
            return OK;
        }
        i++;
    }
    return ERROR;
}
//遍历列表
void traverseList(LinkList L){
    if(L == NULL) return;
    LinkList temp = L->next;
    while (temp != L) {
        printf("%d ",temp->data);
        temp = temp->next;
    }
    printf("\n");
    return;
}