带头节点双向链表实现

发布时间 2024-01-08 10:43:57作者: Rabbit_XIN
#include <stdio.h>
#include <stdlib.h>

#define Elemtype int 
#define ERROR -1
/*
    带头节点的双向链表循环实现
*/
typedef struct Node {
    Elemtype e;
    Node* next;
    Node* front;
}Node,*LinkList;

void InitList(LinkList& pHead) {
    pHead = (Node*)malloc(sizeof(Node));
    pHead->next = pHead;
    pHead->front = pHead;
}

void Visit(Elemtype e) {
    printf("%d ", e);
}

int ListTravel(LinkList pHead) {
    if (pHead->next == pHead)
        return false;
    Node* p;
    p = pHead->next;
    while (p!=pHead)
    {
        Visit(p->e);
        p = p->next;
    }
    return true;
}

void DestoryList(LinkList& pHead) {
    if (pHead == NULL) {
        printf("链表不存在,无需销毁\n");
        return;
    }
    Node* p = pHead->next;
    Node* q = NULL;
    while (p!=pHead)
    {
        q = p->next;
        free(p);
        p = q;
    }
    free(pHead);
    pHead = NULL;
}

void ClearList(LinkList pHead) {
    if (pHead == NULL) {
        printf("链表不存在,无法清空\n");
        return;
    }
    Node* p = pHead->next;
    Node* q = NULL;
    while (p != pHead)
    {
        q = p->next;
        free(p);
        p = q;
    }
    pHead->next = pHead;
    pHead->front = pHead;
}

int ListEmpty(LinkList pHead) {
    if (pHead == NULL) //排除链表不存在
    {
        printf("链表不存在\n");
        return ERROR;
    }
    if (pHead->next != pHead)
        return false;
    return true;
}

int ListLength(LinkList pHead) {
    if (pHead == NULL) {
        printf("链表不存在\n");
        return ERROR;
    }        
    Node* p;
    p = pHead->next;
    int count = 0;
    while (p != pHead)
    {
        ++count;
        p = p->next;
    }
    return count;
}

int GetElem(LinkList pHead, int i, Elemtype& e) {
    if (i < 0 || i >= ListLength(pHead)) {
        printf("不合法的下标\n");
        return ERROR;
    }        
    Node* p;
    p = pHead->next;
    int count = 0;
    while (p!=pHead)
    {
        if (count == i) {
            e = p->e;
            return true;
        }
        count++;
        p = p->next;
    }
}

Node* LocateElem(LinkList pHead, Elemtype x) {
    Node* p;
    if (pHead == NULL) {
        printf("链表不存在\n");
        return NULL;
    }
    p = pHead->next;
    while (p!=pHead)
    {
        if (p->e == x)
            return p;
        p = p->next;
    }
    return NULL;
}

Node* LocateSecondElem(LinkList pHead, Elemtype x) {   // 查询第二次出现的元素位置
    Node* p;
    int count = 0;
    if (pHead == NULL) {
        printf("链表不存在\n");
        return NULL;
    }
    p = pHead->next;
    while (p!=pHead)
    {
        if (p->e == x) {
            count++;
            if (count == 2) {
                return p;
            }    
        }    
        p = p->next;
    }
    return NULL;
}

int ListInsert(LinkList pHead, int i, Elemtype e) {
    if (pHead == NULL) {
        printf("链表不存在\n");
        return ERROR;
    }
    if (i < 0 || i > ListLength(pHead)) {
        printf("不合法的下标\n");
        return ERROR;
    }
    Node* p = pHead;
    Node* q = (Node*)malloc(sizeof(Node));
    int count = 0;
    q->e = e;
    while (count < i)  // 定位到下标为i-1的位置
    {
        p = p->next;
        ++count;
    }
    q->next = p->next;
    p->next = q;
    q->front = p;
    q->next->front = q;
    return 0;
}

int ListDelete(LinkList pHead, int i, Elemtype& e) {
    if (pHead == NULL) {
        printf("链表不存在\n");
        return ERROR;
    }
    if (i < 0 || i >= ListLength(pHead)) {
        printf("不合法的下标\n");
        return ERROR;
    }
    Node* p = pHead;
    Node* q = NULL;
    int count = 0;
    while (count < i) // 定位到第i-1个元素
    {
        p = p->next;
        ++count;
    }
    q = p->next;
    p->next = q->next;
    q->next->front = p;
    e = q->e;
    free(q);
    return 0;
}

int PriorElement(LinkList pHead, Elemtype cur, Elemtype& prior) {
    Node* p = LocateElem(pHead, cur);
    if (p == NULL) {
        printf("找不到这个元素\n");
        return ERROR;
    }
    Node* q = pHead;
    if (q->next == p) {
        printf("第一个元素没有前驱\n");
        return false;
    }
    prior = p->front->e;
    return true;
}

int NextElement(LinkList pHead, Elemtype cur, Elemtype& e) {
    Node* p = LocateElem(pHead, cur);
    if (p == NULL) {
        printf("找不到这个元素\n");
        return ERROR;
    }
    if (p->next == pHead) {
        printf("最后一个元素没有后继\n");
        return ERROR;
    }
    e = p->next->e;
    return true;
}

void InputList(LinkList pHead) {
    int length;
    int elem;
    printf("输入要初始化的集合元素个数:");
    scanf_s("%d", &length);
    printf("分别输入所有元素\n");
    for (int i = 0; i < length; i++)
    {
        scanf_s("%d", &elem);
        ListInsert(pHead, i, elem);
    }
}

int UnionList(LinkList La, LinkList& Lb) {
    Node *p = Lb;
    while (p->next != Lb)
    {
        p = p->next;
    }
    p->next = La->next;
    La->next->front = p;
    La->next = Lb->next;
    Lb->next->front = La;
    free(Lb);
    Lb = NULL;
    return 0;
}

void testGetElem(int times,LinkList pHead) {
    int index,e;
    for (int i = 0; i <times; i++)
    {
        printf("输入需要得到第几个元素的下标:");
        scanf_s("%d", &index);
        if (GetElem(pHead, index, e) != -1) {
            printf("得到的元素为%d\n", e);
        }
    }
}

void testLocate(int times, LinkList pHead) {
    Node* p = NULL;
    int elem;
    for (int i = 0; i < times; i++)
    {
        printf("输入需要找的元素:");
        scanf_s("%d", &elem);
        p = LocateElem(pHead, elem);
        if (p == NULL) {
            printf("没有找到该元素\n");
        }else{
            printf("该元素的地址是:%p 找的元素是:%d\n",p,p->e);
        }
    }
}

void testPriorElem(int times, LinkList pHead) {
    int cur, prior;
    for (int i = 0; i < times; i++)
    {
        printf("输入需要查找前驱的元素:");
        scanf_s("%d", &cur);
        if (PriorElement(pHead, cur, prior) == true) {
            printf("当前元素%d的前驱元素是%d\n",cur, prior);
        }
    }
}

void testNextElem(int times, LinkList pHead) {
    int cur, next;
    for (int i = 0; i < times; i++)
    {
        printf("输入需要查找后继的元素:");
        scanf_s("%d", &cur);
        if (NextElement(pHead, cur, next) == true) {
            printf("当前元素%d的后继元素是%d\n", cur, next);
        }
    }
}

int main() {
    LinkList  La,Lb;
    int e,i;
    InitList(La);
    InputList(La);
    //测试代码
    ListInsert(La, 2, 8);
    ListDelete(La, 1, e);
    printf("删除的元素是%d\n", e);
    testPriorElem(3, La);
    ListTravel(La);
    DestoryList(La);
    return 0;
}