我的数据结构学习之路【第二部分:单链表】

数据结构学习之路(C语言)

  1. 第一部分 线性表之数据表(数组);
  2. 第二部分 线性表之单链表;
  3. 第三部分 栈;
  4. 第四部分 队列;

第二部分:链表(主要指单链表)

简介:与前一章节提到的顺序表不同的是,顺序表的存储格式是数组,是用一篇连续的内存空间来存储数据。而链表的存储形式是一个个在内存中地址不连续的节点来组成的,各个节点之间通过指针关联起来。


注:以下是代码部分,实现了单链表的各种操作

1.构建链表节点的基本格式(未分配内存)

typedef int data_t;
typedef struct node
{
        data_t data;
        struct node *next;
}listnode,*linklist;

2.创建一个链表节点

linklist linknode_create()
{
        linklist H = (linklist)malloc(sizeof(listnode));
        if(H == NULL)
        {
                printf("malloc failed\n");
        }
        H->data = 0;
        H->next = NULL;
        return H;
}

3.链表尾部插入

int linklist_tail_insert(linklist H,data_t value)
{
        linklist new_node = (linklist)malloc(sizeof(listnode));
        if(new_node == NULL)
        {
                printf("malloc failed\n");
                return -1;
        }
        new_node->data = value;
        new_node->next = NULL;
        while(H->next != NULL)
        {
                H = H->next;
        }
        H->next = new_node;
        return 0;
}

4.链表头部插入

int linklist_head_insert(linklist H,data_t value)
{
        if(H == NULL)
        {
                printf("malloc failed\n");
                return -1;
        }
        linklist new_node = (linklist)malloc(sizeof(listnode));
        if(new_node == NULL)
        {
                printf("malloc failed\n");
                return -1;
        }
        new_node->data = value;
        new_node->next = H->next;

        H->next = new_node;

        return 0;
}

5.删除链表中的元素

int linknode_delete(linklist H,int pos)
{
        int i = 0;
        int length;
        if(pos == 0)
        {
                printf("not delete head\n");
        }
        if(linklist_get_length(H,&length) == 0)
        {
                if(pos > length)
                {
                        printf("pos error\n");
                        return -1;
                }
        }
        while(i<pos-1)
        {
                H = H->next;
                i++;
        }
        if(H->next->next != NULL)
        {
                H->next = H->next->next;
        }
        else
        {
                H->next == NULL;
        }
        return 0;
}

6.迭代方法遍历链表数据(iterate)

//iterate
int linklist_show(linklist H)
{
        if(H == NULL)
        {
                printf("malloc failed\n");
                return -1;
        }
        while(H->next != NULL)
        {
                printf("%d  ",H->next->data);
                H = H->next;
        }
        puts("");
        return 0;
}

7.求当前链表的长度

int linklist_get_length(linklist H,int * length)
{
        *length = 0;
        while(H->next != NULL)
        {
                (*length)++;
                H = H->next;
        }
        return 0;
}

8.在链表任一有效位置插入元素

int linklist_insert(linklist H,data_t value ,int pos)
{
        int i = 0;
        int length = 0;
        linklist new_node = (linklist)malloc(sizeof(linklist));
        new_node->data = value;
        linklist_get_length(H,&length);
        while(i < pos-1)
        {
                H = H->next;
                i++;
        }
        new_node->next = H->next;
        H->next = new_node;
        return 0;
}

9.迭代法翻转列表

int linklist_reverse(linklist h)
{
        linklist q = h;
        linklist current = h;
        linklist pre  = NULL;
        linklist next = current->next;
        if(h == NULL)
        {
                printf("invaild linklist\n");
                return -1;
        }
        while(next != NULL)
        {
                current = next;
                next = current->next;
                current->next = pre;
                pre = current;
        }
        h->next = current;
        return 0;
}

10.递归法遍历列表

//recursion
int linklist_recursion_show(linklist H)
{
        H = H->next;
        if(H == NULL)
        {
                puts("");
                return -1;
        }
        printf("%d  ",H->data);
        linklist_recursion_show(H);
        return 0;
}

11.递归法翻转列表

// recursion  reversion
int linklist_reverse_recursion(linklist h,linklist H)
{
        h = h->next;//1  2  3  4  null
        if(h == NULL)
        {
                printf("come here\n");
                return -1;
        }
        linklist_reverse_recursion(h,H);//4  3  2
        if(h->next != NULL)
        {
                linklist q = h->next;// 4
                q->next = h; //changed
                h->next = NULL;//changed
        }
        else
        {
                H->next = h;
        }
        return 0;
}

主函数业务逻辑实现

int main()
{
        int value;
        int length = 0;
        linklist head = linknode_create();
        if(head == NULL)
        {
                printf("headlist create failed\n");
                return -1;
        }
        printf("input:");
        scanf("%d",&value);
        while(value != -1)
        {
                printf("input:");
                //linklist_tail_insert(head,value);
                linklist_head_insert(head,value);
                scanf("%d",&value);
        }
        linklist_show(head);
        if(linklist_get_length(head,&length) == 0)
        {
                printf("%d\n",length);
        }
        linknode_delete(head,2);
        linklist_show(head);
        if(linklist_get_length(head,&length) == 0)
        {
                printf("%d\n",length);
        }
        linklist_insert(head,100,length);
        linklist_show(head);
        change_value(head);
        linklist_show(head);
        linklist_reverse(head);
        linklist_show(head);
        linklist_recursion_show(head);
        linklist_reverse_recursion(head,head);
        linklist_show(head);
        return 0;
}
  

总结

本文介绍了对数据结构中链表的常用操作,函数和结构体声明在linklist.h文件中,具体的函数实现在linklist.c文件中,函数调用,逻辑实现在test.c文件中。
关于栈的实现和操作,请关注下篇文章。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值