数据结构(单向链表)

一、什么是数据结构
1.1、组织存储数据
        ---------》内存(存储)

1.2、研究目的
如何存储数据(变量,数组....)
程序=数据结构+算法
1.3、常见保存数据的方法
数组:保存自己的数据
指针:是间接访问已经存在的空间------------》操作数据,并不能销毁别人的数据
指针数组:并不保存数据,也是指向那个空间,并不能保存数组
二维数组:保存数据的
数据库也其实数据结构,实质上是对复杂数据的一种封装

二、数据与数据之间的关系
2.1、数据的逻辑结构
        数据元素与元素之间的关系

集合:关系平等
线性:元素之间一对一的关系(表,数组,链表)
有当前数据出发,向后最多能找一个后继,先前找最多只能有一个前驱
树形:元素之间一对多(二叉树),从当前找,后继有多个,前驱只有1个
图型结构:元素之间多对多的关系(网状结构)
后继有多个,前驱有多个
2.2、数据的物理结构
1、顺序存储:采用一段连续的内存空间保存元素。
优点:空间连续,访问方便缺点:插入删除需要移动大量的元素需要预分配内存空间容易造成存储空间碎片
2、链式存储:采用一组非连续的内存空间保存元素

缺点:访问元秦效率低优点:插入和删除数据方便不需要预分配内存
3、索引存储:通过关键字构建索引表,通过索引表来来找到数据的存储位置

索引:维护索引表,关键字和其对应得地址

4、散列存储(哈希存储):将数据元素的存储位置与关键码之间建立确定对应关系从而实现查找的存储方式

散列:选取关键字,经过计算,算出对应位置,下次只需要,拿着这个名字,经过计算,就找到位置

2.3、数组与链表区别
2.3.1、数组 线性顺序存储结构
1、空间连续

2、访问数据方便(O(1))

3、数据插入、删除复杂,需要移动大量数据(O(n))

4、预分配内存空间

5、容易产生内存碎片

1、按照指定字节对齐

2、注意结构成员分布

2.3.2、链表 线性链式结构
1、空间不连续

2、访问数据不方便(O(n))

3、数据的插入、删除方便,时间复杂度(O(1))

4、不需要预分配空间,只需申请一个新的节点插入进去即可

5、能够利用内存空间中比较小的碎片

注意:说数据属于那种关系的时候,两种都说。

2.4、物理结构
1、线性结构:

顺序表:-----》数组

链式表:-----》链表

2、链表:

单向链表

有头链表:有一个头结点进行操作,只不过没有数据

无头链表:没有上述的东西

3、封装

--------》高内聚、低耦合

低耦合,关联程度低

高内聚,一个函数干一件事

面向过程的编程思想:第一步干什么,第二步3干什么....

面向对象的编程思想,封装性比较好

用什么来做什么

冰箱----------------------》

属性:特性(变量)

行为:装东西(函数)

三、链表的操作
1、创建头结
Link_t *Create_link()
{
    Link_t *link = malloc(sizeof(link));
    if(NULL == link)
    {
        perror("create error");
        return NULL;
    }
    link->clen = 0;
    link->phead = NULL;
    return link;
}

2、头插

int push_link_join(Link_t *plink,DATATYPE data)
{
    Link_Node_t *pnode = malloc(sizeof(Link_Node_t));
    if(NULL == pnode)
    {
        perror("fail node");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;
    pnode->pnext = plink->phead;
    plink->phead = pnode;
    plink->clen++;
    return 0;
}

3、尾插

int tail_insert(Link_t *plink,DATATYPE data)
{
    Link_Node_t *pnode = malloc(sizeof(Link_Node_t));
    if(NULL == pnode)
    {
        perror("fail node");
        return -1;
    }
    pnode->data = data;
    pnode->pnext = NULL;
    Link_Node_t *p;
    p = plink->phead;
    if(p == NULL)
    {
        p = pnode;
    }
    while(p->pnext)
    {
        p = p->pnext;
    }
    pnode->data = data;
    pnode->pnext = NULL;
    p->pnext = pnode;
    plink->clen++;
   printf("%d\n",pnode->data);
}

4、遍历

int travel_link(Link_t *plink)
{
    int i = 0;
    Link_Node_t *p ;
    p = plink->phead;
    while(p != NULL)
    {
        printf("num = %d,data = %d\n",i,p->data);
        ++i;
        p = p->pnext;
    }
}

5、头删

int delete_link_first(Link_t *plink)
{
    Link_Node_t *pnode;
    if(plink->phead == NULL)
    {
        return 0;
    }
    else
    {
        pnode = plink->phead;
        plink->phead = pnode->pnext;
        free(pnode);
        plink->clen--;
    }
    return 0;
}

6、尾删

int delete_link_tail(Link_t *plink)
{
    Link_Node_t *pnode;
    if(plink->phead == NULL)
    {
        return 0;
    }
    else if(plink->clen == 1)
    {
        delete_link_first(plink);
    }
    else
    {
        pnode = plink->phead;
        while(pnode->pnext->pnext != NULL)
        {
            pnode = pnode->pnext;
        }
        free(pnode->pnext);
        pnode->pnext = NULL;
    }
}

7、查对应结点

Link_Node_t *select_link(Link_t *link,DATATYPE data)
{
    Link_Node_t *pnode  = link->phead;
    while(pnode->data != data)
    {
        pnode = pnode->pnext;
    }
    printf("num = %d\n",pnode->data);
    return pnode;
}

8、改

Link_Node_t *alter_link(Link_t *link,DATATYPE data,DATATYPE wishdata)
{
    Link_Node_t *pnode = select_link(link,data);
    pnode->data  = wishdata;
    printf("wishdata = %d\n",pnode->data);
    return pnode;
}

9、销毁

int destory_link(Link_t *link)
{
    Link_Node_t *pnode = link->phead;
    if(pnode == NULL)
    {
        free(link);
        return 0;
    }
    else
    {
        while(link->clen != 0)
        {
            delete_link_first(link);
        }
        return 0;
    }
    free(link);
}

10

11

12

13

//查找倒数第k个
int find_reverse_k(Link_t *plink,int k)
{   
    int i = 0;
    Link_node_t *p = plink->phead;
    Link_node_t *q = plink->phead;
    for(i = 0;i < k;i++)
    {
        
        if(p == NULL)
        {
            return -1;
        }
        p = p->pnext;
    }
    while(p != NULL)
    {
        p = p->pnext;
        q = q->pnext;
    }
    printf("reveser_k_data = %d\n",q->data);
    return 0;
}

14

//逆序
int reveser_link(Link_t *plink)
{
    if(plink->phead == NULL)
    {
        printf("link is NULL\n");
        return -1;
    }
    Link_node_t *p = plink->phead;
    Link_node_t *q = plink->phead;
    plink->phead = NULL;
    while(p != NULL)
    {
        p = p->pnext;
        q->pnext = plink->phead;
        plink->phead = q;
        q = p;
    }
    return 0;
}

15

//插入法排序
int insert_sort_link(Link_t *plink)
{
    Link_node_t *p = plink->phead->pnext;
    Link_node_t *q = plink->phead;
    q->pnext = NULL;
    while(p != NULL)
    {
        q = p;
        p = p->pnext;
        if(q->data < plink->phead->data)
        {
            q->pnext = plink->phead;
            plink->phead = q;
        }
        else //if(m->data < q->data )
        {
            Link_node_t *m = plink->phead;
            while(m->pnext != NULL && m->pnext->data < q->data)
            {
                m = m->pnext;
            }
            q->pnext = m->pnext;
            m->pnext = q;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值