双向循环链表

双向循环链表

基本结构

双向循环链表_第1张图片

typedef int ElemType;
typedef int DataType;

typedef struct DNode
{
    ElemType data;
    struct DNode *pre, *next;
}DNode, *DLinkList;

函数

  • 创建双向循环链表
void ListCreate(DLinkList L, int n)
{
    int i;
    DLinkList p, s;
    p = L;

    L->pre = L->next = L;                           //表为空时,前驱和后继都指向自己

    for(i = 0; i < n; i ++)
    {
        s = (DLinkList)malloc(sizeof(DNode));
        scanf("%d", &s->data);

        p->next = s;                                //前驱和后继相互连接
        s->pre = p;

        s->next = L;                             //头和尾互指
        L->pre = s;
        p = s;
    }
}
  • 插入结点
void ListInsert(DLinkList L, int i , ElemType e)
//在第i个位置插入元素e
{
    DLinkList s, p = L;
    while(p->next != L && i > 1)                       //寻找第i-1个结点
    {
        p = p->next;
        i--;
    }

    s = (DLinkList)malloc(sizeof(DNode));
    s->data = e;

    s->next = p->next;
    //if(p->next != NULL) //非循环链表需要判断是否为最后一个结点
        p->next->pre = s;
    s->pre = p;
    p->next = s;
}
  • 删除结点
void ListDelete(DLinkList L, int i, ElemType *e)
//删除第i个结点, 并由*e返回其值
{
    DLinkList p = NULL, q = L;
    while(q->next != L && i >= 1)                  //直到第i个结点
    {
        p = q;                                  //p为q的前驱
        q = q->next;
        i--;
    }

    p->next = q->next;
    //if(q->next != NULL) //非循环链表需要判断是否为最后一个结点
        q->next->pre = p;
    *e = q->data;
    free(q);
}
  • 正序遍历
void ListTraverse(DLinkList L)
{
    DLinkList p = L;
    while(p->next != L)
    {
        p = p->next;
        printf("%d", p->data);

    }
    printf("\n");
}
  • 逆序遍历
void ListReTraverse(DLinkList L)
{
    DLinkList p = L;
    while(p->pre != L)
    {
        p = p->pre;
        printf("%d", p->data);
    }
    printf("\n");
}

测试代码

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;
typedef int DataType;

typedef struct DNode
{
    ElemType data;
    struct DNode *pre, *next;
}DNode, *DLinkList;

void ListCreate(DLinkList L, int n)
{
    int i;
    DLinkList p, s;
    p = L;

    L->pre = L->next = L;                           //表为空时,前驱和后继都指向自己

    for(i = 0; i < n; i ++)
    {
        s = (DLinkList)malloc(sizeof(DNode));
        scanf("%d", &s->data);

        p->next = s;                                //前驱和后继相互连接
        s->pre = p;

        s->next = L;                             //头和尾互指
        L->pre = s;
        p = s;
    }
}

void ListInsert(DLinkList L, int i , ElemType e)
//在第i个位置插入元素e
{
    DLinkList s, p = L;
    while(p->next != L && i > 1)                       //寻找第i-1个结点
    {
        p = p->next;
        i--;
    }

    s = (DLinkList)malloc(sizeof(DNode));
    s->data = e;

    s->next = p->next;
    //if(p->next != NULL) //非循环链表需要判断是否为最后一个结点
        p->next->pre = s;
    s->pre = p;
    p->next = s;
}

void ListDelete(DLinkList L, int i, ElemType *e)
//删除第i个结点, 并由*e返回其值
{
    DLinkList p = NULL, q = L;
    while(q->next != L && i >= 1)                  //直到第i个结点
    {
        p = q;                                  //p为q的前驱
        q = q->next;
        i--;
    }

    p->next = q->next;
    //if(q->next != NULL) //非循环链表需要判断是否为最后一个结点
        q->next->pre = p;
    *e = q->data;
    free(q);
}

void ListTraverse(DLinkList L)
{
    DLinkList p = L;
    while(p->next != L)
    {
        p = p->next;
        printf("%d", p->data);

    }
    printf("\n");
}

void ListReTraverse(DLinkList L)
{
    DLinkList p = L;
    while(p->pre != L)
    {
        p = p->pre;
        printf("%d", p->data);
    }
    printf("\n");
}
int main()
{
    DNode L;
    int e;
    ListCreate(&L, 3);
    ListTraverse(&L);

    ListInsert(&L, 1, 0);
    ListTraverse(&L);

    ListInsert(&L, 5, 7);
    ListTraverse(&L);

    ListDelete(&L, 1, &e);
    ListTraverse(&L);

    ListDelete(&L, 4, &e);
    ListTraverse(&L);

    ListReTraverse(&L);
}

你可能感兴趣的:(双向循环链表)