数据结构——基础及C实现demo

48 篇文章 0 订阅
本文深入探讨了算法与数据结构的基础,强调了它们在程序设计中的重要性。线性表作为基础数据结构,包括顺序存储和链式存储两种方式。文章详细讲解了顺序存储结构的栈和队列,以及它们在实际问题中的应用,如中缀表达式转后缀表达式。此外,还介绍了几种排序算法,如冒泡排序、选择排序、插入排序、希尔排序和归并排序,分析了它们的时间复杂度和适用场景。最后,提到了堆排序和二叉树等概念,为读者提供了丰富的算法实践知识。
摘要由CSDN通过智能技术生成

一、算法和数据结构基础

	程序 = 数据结构 + 算法 
	
	数据结构是计算机存储、组织数据的方式。
	
		数据结构只是静态的描述了数据元素之间的关系,
		高效的程序需要在数据结构的基础上设计和选择算法。
	
	算法是为了解决实际问题而设计的。
	数据结构是算法需要处理的问题载体。

算法效率的度量:
	1.事后统计法
	2.事前分析估算

算法的时间复杂度,指最坏时间复杂度;
大O表示法表示算法的时间复杂度,只有常数项记作 1 .
操作数量的估算可以作为时间复杂度的估算。

二、线性表概念

线性表 	是零个或多个数据元素的有限序列。

特性:
	数据元素之间是有序的。
	数据元素个数是有限的。
	数据元素类型是相同的。

存储方式:
		顺序存储结构
				用一段地址【连续的】存储单元依次存储线性表的数据元素。	
		链式存储结构
				用一段地址【非连续的】存储单元存储线性表的数据元素。	

三、线性表——顺序存储结构

四、线性表——链式存储结构

  1. 链式存储
    demo Test_LinkList()

  2. 循环链表
    在这里插入图片描述

    最优链表就是:指针域和数据域分开。
    取数据时,转换指针类型。
    

    demo Test_CircleLinkList()

    利用循环链表解决约瑟夫问题。在这里插入图片描述
    demo Test_CircleLinkList_Josephus_problem()

  3. 双向链表
    在这里插入图片描述

五、受限线性表——栈(stack)

先进后出

  1. 栈的顺序存储
    在这里插入图片描述
    demo Test_SeqStack()

  2. 栈的链式存储
    demo Test_LinkStack()

六、受限线性表——队列(queue)

先进后出。
First In first out.
在这里插入图片描述

  1. 顺序存储
    demo Test_SeqQueue()

七、栈的应用

  1. 就近匹配
    demo Test_InfixToSuffix()

  2. 中缀表达式转后缀表达式

    后缀表达式就是计算机的计算顺序
    	eg: 5 + 4 => 5 4 +
    中缀表达式符合人的表达方式。
    	eg:1 + 2 * 3 => 1 2 3 * +
    

    在这里插入图片描述
    eg:
    在这里插入图片描述

    demo Test_SuffixGetResult()

八、树

在这里插入图片描述
在这里插入图片描述

存储方式:
在这里插入图片描述

九、树——二叉树

  1. 概念
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    eg:
    在这里插入图片描述
    在这里插入图片描述

  2. List item

十、算法——排序

在这里插入图片描述
在这里插入图片描述

十一、算法——冒泡排序

在这里插入图片描述
源码链接:Algorithm_BubbleSort_main()

十二、算法——选择排序

	每一次从待排序的数据元素中选出最小(最大)的一个元素,存放在序列的起始位置,
然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法。

源码链接:Algorithm_SelectSort_main()

十三、算法——插入排序

1、将待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列;

2、取出下一个元素,在已经排序的元素序列中从后向前扫描;

3、如果该元素(已排序)大于新元素,将该元素移到下一位置;

4、重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

5、将新元素插入到该位置后;

6、重复步骤2~5。


适合:
	1.元素序列基本有序的情况下
				基本有序:小的都在左边,大的都在右边
	2.	元素个数比较小的时候

在这里插入图片描述

源码链接:Algorithm_InsertionSort_main()

十四、算法——希尔排序

希尔排序是特殊的插入排序

时间复杂度
	希尔排序的时间复杂度依赖于增量序列的函数,有人在大量的实验后得出的结论:
	当n在某个特定的范围后,在最优的情况下,希尔排序的时间复杂度为O(n1.3),在最差的情况下,希尔排序的时间复杂度为:O(n2).
空间复杂度
	希尔排序的空间复杂度:O(1).

在这里插入图片描述
源码链接:Algorithm_ShellSort_main()

十五、算法——快速排序

1. 首先取出一个key,一般取第一个元素
2. 先从后往前遍历,如果数组中的数据小于了key,那么就将从前往后未比较过的第一个位置即fisrt位置替换为该数据
3. 然后从前往后遍历,如果数组中的数据大于了key,那么就将从后往前的第一个比较过数据位置替换
4. 然后直到左右两边的位置重合,说明key就找到了正确的位置,每次循环就能找到一个数的正确位置
5. 然后将key左右两边的数据分为两组,递归调用自己。

源码链接:Algorithm_QuickSort_main()

十六、算法——归并排序

第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾,将另一序列剩下的所有元素直接复制到合并序列尾

归并排序其实要做两件事:
(1)“分解”——将序列每次折半划分(递归实现)
(2)“合并”——将划分后的序列段两两合并后排序

如何合并?

在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。

这两个有序序列段分别为 R[low, mid] 和 R[mid+1, high]。

先将他们合并到一个局部的暂存数组R2中,带合并完成后再将R2复制回R中。

我们称 R[low, mid] 第一段,R[mid+1, high] 为第二段。

每次从两个段中取出一个记录进行关键字的比较,将较小者放入R2中,最后将各段中余下的部分直接复制到R2中。

经过这样的过程,R2已经是一个有序的序列,再将其复制回R中,一次合并排序就完成了。

在这里插入图片描述
源码链接:Algorithm_MergeSort_main()

十七、堆排序

最好和最坏的情况时间复杂度都是O(nlogn),空间复杂度O(1)。

堆是一种数据结构,一种叫做【完全二叉树】的数据结构。

堆的分类:
	大顶堆:每个节点的值都大于或者等于它的左右子节点的值。
	小顶堆:每个节点的值都小于或者等于它的左右子节点的值。

在这里插入图片描述

上面大小顶堆的逻辑结构映射到数组中,就是下边这样

9	5	8	2	3	4	7	1
1	3	5	4	2	8	9	7
这个数组arr逻辑上就是一个堆。

从这里我们可以得出以下性质(重点)

对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]

源码链接:Algorithm_HeapSort_main()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值