数据结构(1)—基础概念、单向链表

一、数据结构相关概念

1.程序 == 数据结构 + 算法

数据结构:描述数据存储和操作的结构

2.. 衡量代码的质量和效率:
(1)时间复杂度:数据量的增长与程序运行时间的增长所呈现的比例函数关系,称为时间渐进复杂度函数,也简称时间复杂度

        常见的时间复杂度(低 -> 高):

        O(1):程序运行时间维持恒定

        O(logn):程序刚开始运行时间可能增长较快,但经过一定数据量后,程序运行时间趋于恒定

        O(n):程序运行时间随数据量增长呈现固定的比例关系                                                         

        此外还有O(nlogn)、O(n^2)、O(n^3)、O(2^n)等

(2)空间复杂度:数据的增长与程序占据空间的增长所呈现的比例函数关系,称为空间复杂度

3.数据结构

逻辑结构:线性结构:表(一对一)非线性结构:

                                    树(一对多)、图(多对多)

存储结构:顺序存储 链式存储 散列存储 索引存储

常见的数据结构:链式表  顺序栈  链式栈  顺序队列  链式队列  二叉树

二、链表

1.(1)顺序表(数组)特点:存储空间连续,访问元素方便无法利用小的空间,必须连续的大空间,顺序表元素必须为有限的(不存在无限连续的空间)缺点:插入和删除效率低

(2)链表特点:存储空间不需要连续,可以利用一些小的存储空间,链表元素可以没有上限,插入和删除效率高 缺点:链表特点:访问元素不方便

2.(1)单向链表:只能通过链表节点找到后一个节点,访问链表元素的方向是单向的

   (2)双向链表:能够通过链表节点找到前一个节点和后一个节点

   (3)循环链表:能够通过第一节点快速找到最后一个节点,能够通过最后一个节点快速找到第一个节点

   (4)内核链表:Linux内核所采用的一种通用的链表结构

3.单向链表

(1)定义初始链表节点类型

        /* 链表存放数据的类型 */

        typedef int datatype;

        /* 链表节点类型 */

        typedef struct node {

                datatype data; //存放数据空间

                struct node *pnext; //存放下一个节点地址

        }linknode;

(2)创建空链表

创建一个空的链表节点,数据无需赋值,pnext必须赋值为NULL,此时该节点就为最后一个节点,将节点地址返回

linknode *create_empty_linklist(void)
{
        linknode *ptmpnode = NULL;
        ptmpnode = malloc(sizeof(linknode));
        if (NULL == ptmpnode)                                                                                                                      {
                perror("fail to malloc");
                return NULL;
        }
        ptmpnode->pnext = NULL;                                                                                                      }

(3)链表的头插法:在链表开头插入一个元素

具体思路:先申请新的节点空间,申请的新的节点空间的值就为需要存放的数据,它的pnext就为空白节点的pnext,而空白节点的pnext变为新申请的节点的地址,具体实现如下:

/* 插入一个节点 */
int insert_head_linklist(linknode *phead, datatype tmpdata)
{
        linknode *ptmpnode = NULL;
        //申请空间
        ptmpnode = malloc(sizeof(linknode));
        if (NULL == ptmpnode)
        {
                perror("fail to malloc");
                return -1;
        }
        //存放数据
        ptmpnode->data = tmpdata;
        //存放下一个节点地址
        ptmpnode->pnext = phead->pnext;
        //更新空白的节点的pnext
        phead->pnext = ptmpnode;
        return 0;
}

(4)链表的遍历:访问链表中每个节点元素

方法一:遍历链表中的每一个元素,多用于遍历链表中所有节点元素

void show_linklist(linknode *phead)
{
        linknode *ptmpnode = NULL;
        ptmpnode = phead->pnext;
        while (ptmpnode != NULL)
        {
                printf("%d ", ptmpnode->data);
                ptmpnode = ptmpnode->pnext;
        }
        printf("\n");
        return;
}

方法二:只能遍历链表中除最后一个节点剩余的元素,多用于找到链表最后一个节点

while(p->pnext != NULL)

{

        p = p->pnext;

}

(5)链表元素删除:从链表中删除指定的元素

①定义两个指针ptmpnode用来遍历链表查找要删除的节点元素,pprenode永远是ptmpnode的前一个节点

②当ptmpnode找到要删除的节点元素,让pprenode->pnext赋值为ptmpnode->pnext

③将要删除的节点元素释放(free,此时ptmpnode变为野指针,所以要进行第四步)

④让ptmpnode判断下一个节点元素是否要删除,直到该指针指向NULL为止

int delete_linklist(linknode *phead, datatype tmpdata)
{
        linknode *pprenode = NULL;
        linknode *ptmpnode = NULL;
        pprenode = phead;
        ptmpnode = phead->pnext;
        while (ptmpnode != NULL)
        {
                if (ptmpnode->data == tmpdata)
                {
                        pprenode->pnext = ptmpnode->pnext;
                        free(ptmpnode);
                        ptmpnode = pprenode->pnext;
                }
                else
                {
                        ptmpnode = ptmpnode->pnext;
                        pprenode = pprenode->pnext;
                }
        }
        return 0;
}

小tips:在用visual编写代码是,同时编译几个文件时,可以使用makefile工具,需要新建一个

filemake文件,以下面这种格式编写:                                                                                           

要生成的文件:依赖的所有文件                                                                                                       

        生成命令方(不要忘记tab键)                                                                                               

最终编译时只需输入make即可编译完成,成功后就可以运行程序

                                                                                                      



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值