数据结构day5(双向循环链表)

 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

#ifndef __RFF_H__
#define __RFF_H__

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

typedef float datedef;

/*
typedef struct
{
char name[20];
int age;
int score;
}student;
*/

typedef struct Node
{
    union // 数据域
    {
        int len;      // 头结点的数据域 (链表长度)
        datedef date; // 其他结点的数据域
    };
    struct Node *next; // 指针域
    struct Node *pre;
} *rdlinklist, RDLinklist;

rdlinklist creat(int flag); // 创建新链表

// int indel(dlinklist L,dlinklist p);             //p后删除 (中删)
// int insert(dlinklist L,dlinklist p,datedef e);  //p后插入 (中插)

void output(rdlinklist L);   // 正向遍历
void T_output(rdlinklist L); // 逆向遍历

int h_insert(rdlinklist L, datedef s); // 头插
int h_del(rdlinklist L);               // 头删
int r_insert(rdlinklist L, datedef e); // 尾插
int r_del(rdlinklist L);               // 尾删

void L_free(rdlinklist L); // 链表释放

#endif

rdlinklist creat(int flag) // 创建双向链表新结点
{
    rdlinklist L = (rdlinklist)malloc(sizeof(RDLinklist));
    if (L == NULL)
    {
        return NULL;
    }
    if (flag == 1) // 头结点
    {
        L->len = 0;
        L->next = L; // 初始化
        L->pre = L;
    }
    else if (flag == 0) // 其他结点
    {
        L->date = 0;
        L->next = NULL; // 初始化
        L->pre = NULL;
    }
    return L;
}

/*
int insert(dlinklist L,dlinklist p,datedef e)  //p后插入 (中插)
{
dlinklist s=creat(0);
strcpy(s->date,e);
s->next=p->next;
s->pre=p;
p->next->pre=s;
p->next=s;
L->len++;
return 0;
}

int indel(dlinklist L,dlinklist p)            //p后删除 (中删)
{
    dlinklist q=p->next;
    p->next=q->next;
    L->len--;
    free(q);
    q=NULL;
return 0;
}

*/

int h_insert(rdlinklist L, datedef s) // 头插
{
    if (L == NULL)
    {
        printf("头插失败\n");
        return -1;
    }
    rdlinklist q = creat(0);
    if (q == NULL)
    {
        return -1;
    }
    q->date = s;
    q->next = L->next;
    q->pre = L;
    L->next->pre = q;
    L->next = q;
    L->len++;
    return 0;
}

void output(rdlinklist L) // 正向遍历
{
    if (L->next == L || L == NULL)
    {
        printf("遍历失败\n");
    }
    printf("正向遍历是:\n");
    rdlinklist p = L;
    while (p->next != L)
    {
        p = p->next;
        printf("%f\t", p->date);
    }
    puts("");
    printf("该链表有%d个元素。\n", L->len);
}
/*
 *for(int i=0;i<p->len;i++)
 *{
 *p=p->next;
 *printf("%d\t",p->date);
 *}
 *puts("");
 */

void T_output(rdlinklist L) // 逆向遍历
{
    if (L->next == L || L == NULL)
    {
        printf("遍历失败\n");
    }
    printf("逆向遍历是:\n");
    rdlinklist p = L;

    while (p->pre != L)
    {
        p = p->pre;
        printf("%f\t", p->date);
    }

    puts("");
    printf("该链表有%d个元素。\n", L->len);
}

int r_insert(rdlinklist L, datedef e) // 尾插
{
    if (L == NULL)
    {
        printf("链表不存在\n");
        return -1;
    }
    rdlinklist p = creat(0);
    p = L;

    rdlinklist s = creat(0);
    s->date = e;
    s->pre = L->pre;
    s->next = L;
    L->pre->next = s;
    L->pre = s;
    L->len++;
}

int h_del(rdlinklist L) // 头删
{
    if (L->next == L || L == NULL)
    {
        printf("删除失败\n");
        return -1;
    }
    rdlinklist p = L->next;
    L->next = p->next;
    p->next->pre = L;
    L->len--;
    free(p);
    p = NULL;
}

int r_del(rdlinklist L) // 尾删
{
    if (L == NULL || L->next == L)
    {
        printf("操作失败\n");
        return -1;
    }
    rdlinklist p = L->pre;
    L->pre = p->pre;
    p->pre->next = L;
    free(p);
    p = NULL;
    L->len--;
}

void L_free(rdlinklist L) // 链表释放
{

    if (L == NULL)
    {
        return;
    }

    int n = L->len;
    for (int i = 0; i < n; i++)
    {
        h_del(L); // 头删
    }
    free(L);
    L = NULL;
}

int main(int argc, const char *argv)
{

    rdlinklist L = creat(1);

    int n;
    datedef s, e;

    printf("你要头插的元素个数:");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        printf("你要头插的元素是:");
        scanf("%f", &s);
        h_insert(L, s); // 头插
    }
    output(L);
    T_output(L); // 逆向遍历

    printf("你要尾插的元素个数:");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        printf("你要尾插的元素是:");
        scanf("%f", &s);
        r_insert(L, s); // 尾插
    }
    output(L);
    T_output(L);

    h_del(L); // 头删
    output(L);

    r_del(L); // 尾删
    output(L);

    L_free(L); // 链表释放
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值