初级程序员软考重点6 数据结构与算法
初级程序员软考重点6:数据结构与算法
- 一、数据结构和算法
- 1. 逻辑结构
- (1)线性结构
- (2)非线性结构
- 2. 存储结构
- 3. 顺序表
- 4. 链表
- 二、数组和字符串
- 三、矩阵
- 1. 特殊矩阵
- 2. 非特殊矩阵
- 3. 矩阵乘法
- 三、栈和队列
- 1. 队列(先进先出,FIFO——first in first out)
- 2. 栈(先进后出,FILO——first in last out)
- 四、树
- 1. 树的基本概念
- 2. 二叉树
- (1)一些概念
- 满二叉树
- 完全二叉树
- 非完全二叉树
- (2)二叉树的特性
- 3. 树的遍历
- 4. 特殊二叉树
- (1) 二叉排序树
- (2) 哈夫曼树
- 五、图
- 1. 图的分类
- (1)有向图
- (2)无向图
- (3)连通图
- (4)完全图
- 2. 图的转换:无向图转邻接矩阵
- 无向图转换的邻接矩阵为对称矩阵。
- 有向图转邻接矩阵
- 3. 度
- (1)入度
- (2)出度
- 4. 有向图转邻接链表
- 六、算法特性与复杂度
- 1. 算法的特性
- 2. 算法评价指标
- 3. 时间复杂度
- 4. 空间复杂度
- 七、查找
- 1. 顺序查找
- 2. 二分查找(折半查找)
- (1)二分法查找循环算法
- (2)二分法排序递归算法
- 3. 散列表查找:
- (1)线性探查法
- (2)拉链法
- 八、排序
- 1. 基本概念
- 2. 插入类排序
- (1) 直接插入排序
- (2)希尔排序
- 3. 交换类排序
- (1)冒泡排序
- (2)快速排序
- 4. 选择类排序
- (1)直接选择排序
- (2) 堆排序
- 5. 归并排序
- 6. 基数排序
- 7. 总结
一、数据结构和算法
数据结构:元素之间的关系,分为逻辑结构和存储结构。
1. 逻辑结构
(1)线性结构
每个元素前、后最多都只能有一个节点,如:线性表、栈、队列、数组、串
(2)非线性结构
如:二维数组、多维数组、树、图等
2. 存储结构
- 顺序存储
- 链接存储
3. 顺序表
含有n个元素的线性表采用顺序存储,等概率删除其中任一个元素,平均需要移动 n − 1 2 \frac{n-1}{2} 2n−1个元素。
4. 链表
链表中的每个元素称为结点,每个结束是一个结构体变量,分为:
数据部分
指针变量:通常具有指向自身结构体类型的指针变量,存放下一结点的地址,最后一个结点的地址为NULL(单链表)。
尾结束:最后一个结点
尾指针:找尾结点的指针
头结点:第一个结点
头指针:指向头结点的指针变量
首结点:第一个有效结点
循环链表,尾指针指向头结点地址。
双向链表:每个结点增加一个front用来存放前一个结点地址。
二、数组和字符串
数组:表示n个数据类型相同的元素所组成的序列。
字符串:字符构成的一维数组。
- 空串: 没有任何字符
- 空白串:字符都是不可见的
- 子串:串中任意个连续的字符组成的子序列
- 非平凡子串:非空且不同于字符串本身
- 串的模式匹配:模式串在主串中首次出现的位置
- 字符串的比较:从左到右按ASCIID码值进行比较
三、矩阵
1. 特殊矩阵
- 三角矩阵:上三角矩阵、下三角矩阵(存非零元素即可)。
- 对角矩阵
- 对称矩阵: A i j = A j i A_{ij}=A_{ji} Aij=Aji
- 反对称矩阵: A i j = − A j i A_{ij}=-A_{ji} Aij=−Aji
2. 非特殊矩阵
- 稀疏矩阵:使用三元组存储
3. 矩阵乘法
三、栈和队列
1. 队列(先进先出,FIFO——first in first out)
- 队尾: rear
- 队头:front
2. 栈(先进后出,FILO——first in last out)
四、树
1. 树的基本概念
- 父结点
- 子结点
- 兄弟结点
- 叶子结点:没有子结点
- 结点的度:结点有几个子结点
- 树的度:所有结点度最大的值
- 二叉树:树的度不超过2
- 层(深度、高度)
2. 二叉树
(1)一些概念
满二叉树
每一层都不能增加结点
完全二叉树
除了最后一层,都不能增加结点。 最后一层左侧连续有,右侧连续无。
非完全二叉树
除了最后一层,都不能增加结点。但不满足最后一层左侧连续有、右侧连续无的条件 。
(2)二叉树的特性
- 每一层上最多有 2 n − 1 2^{n-1} 2n−1个节点
- 深度为k的二叉树最多有 2 k − 1 2_k-1 2k−1个节点
- 如果对一棵有n个结点的完全二叉树的结点按层序编号,有:
如果i=1,则结点i无父结点,二叉树的根;如果i>1,则父结点是 i/2取整。
如果2i>n,则结点i为叶子结点,无左子结点;否则,其左子结点是结点2i。
如果2i+1>n,则结点i无右子结点,否则,其右子结点是结点2i+1。
3. 树的遍历
- 前序/先序遍历
- 中序遍历
- 后序遍历
- 层序遍历
4. 特殊二叉树
(1) 二叉排序树
- 二叉排序/查找树
- 左子树小于根
- 右子树大于根
值最小的结点无左子树
值最大的结点无右子树。
二叉查找树的中序遍历序列为从小到大排列的序列
每一层从左到右进行遍历的序列为从小到大排列的序列。
(2) 哈夫曼树
- 树的路径长度:从树根到树中每一结点的长度之路
- 权:在一些应用中,赋予树中结点的一个有特定含义的数
- 带权路径长度:结点到树根之间的路径长度与该结点上权的乘积
- 树的代价:树的带权路径长度
- 哈夫曼树的构造
五、图
1. 图的分类
(1)有向图
一个顶点到另一个顶点是有方向的;
(2)无向图
(3)连通图
任意两个顶点之间都有一个路径相连。
- 强连通:有方向的情况下都连通
- 弱连通:不考虑方向的连通
(4)完全图
- 在无向图中,若每对顶点之间都有一条边相连,则为完全图。
- 在有向图中,若每对顶点之间都有两条有向连互连,则为完全图。
n个顶点的无向图和有向图的完全图边的个数计算:
- 无向图: n ∗ ( n − 1 ) 2 \frac{n*(n-1)}{2} 2n∗(n−1)
- 有向图: n ∗ ( n − 1 ) n*(n-1) n∗(n−1)
2. 图的转换:无向图转邻接矩阵
用一个n阶的方阵R来存放图中各结点的关联信息。
无向图转换的邻接矩阵为对称矩阵。
有向图转邻接矩阵
无穷大表示无连接。
3. 度
(1)入度
指向该结点的边的数量
(2)出度
从该结点指出去的边的数量。
4. 有向图转邻接链表
六、算法特性与复杂度
1. 算法的特性
- 有穷性
- 确定性
2. 算法评价指标
- 正确性
- 友好性
- 可读性
- 健壮性
- 效率
3. 时间复杂度
常见的算法时间复杂度:
O ( 1 ) < ( l o g 2 n ) < O ( n ) < O ( n l o g 2 n ) < O ( n 2 ) < O ( n 3 ) < O ( 2 n ) O(1) < (log_2n) <O(n) <O(nlog_2n) <O(n^2)<O(n^3)<O(2^n) O(1)<(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(2n)
- 二分查找: l o g 2 n log_2n log2n
- 一次循环: O(n)
- 插入、冒泡、选择排序: O ( n 2 ) O(n^2) O(n2)
4. 空间复杂度
临时空间占用大小。
七、查找
1. 顺序查找
从头到尾依次查找。
平均查找长度: n + 1 2 \frac{n+1}{2} 2n+1
2. 二分查找(折半查找)
- 前提:有序表、顺序表。
- 折半出现小数时向下取整。
- 折半查找的时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)
- 折半查找成功时关键字的比较次数最多为 l o g 2 n + 1 log_2n+1 log2n+1次。
(1)二分法查找循环算法
int biSearch(int r[], int low, int high, int key){int mid;while(low<=high ){mid = (low+high)/2;if(key == r[mid]) return mid;else if(key<r[mid]) high = mid-1;else low = mid+1;}return -1;
}
int main(){int data[] = {1,2,3,4,5};int low=0;int high=sizeof(data) /sizeof(int);int key=3;int find = biSearch(data, low, high, key);printf("result: %d", find);
}
(2)二分法排序递归算法
int biSearchRecursion(const int r[], int low, int high, int key){int mid;if(low<=high){mid = (low + high) /2;if(key ==r[mid]) return mid;else if(key<r[mid]) return biSearchRecursion(r, low, mid-1, key);else return biSearchRecursion(r, mid+1, high, key);}return -1;
}
int main(){const int data[] = {1,2,3,4,5};int low=0;int high=sizeof(data) /sizeof(int);int key=3;int find = biSearchRecursion(data, low, high, key);printf("result: %d", find);return 0;
}
3. 散列表查找:
(1)线性探查法
- 示例散列函数: h = k e y h=key%7 h=key
- 冲突解决:放在后面最近的空格里
(2)拉链法
仍使用散列函数,用链地址法。按关键码构造链,链的数量与关键码一致。
八、排序
1. 基本概念
- 稳定排序:相同值排序后保持前后序号
- 不稳定排序:相同值排序后序号不保持原来顺序
2. 插入类排序
(1) 直接插入排序
插入的元素与现有元素挨个比较,每次从元素前面一个元素比较,比前一元素小的话就继续往前比较。
直接插入排序在元素基本有序时比较有优势。
代码示例:
void insertSort(int data[], int n){int i,j;int tmp;for(i=1;i<n;i++){if(data[i]<data[i-1]){tmp = data[i];data[i] = data[i-1];// 元素往后移for(j=i-2;j>=0 && data[j]>tmp;j--){data[j+1]=data[j];}data[j+1]=tmp;}}
}int main(){int data[] = {3,4,5,3,5,1,22};insertSort(data, 7);for(int i=0;i<7;i++){printf("%d=%d\n", i, data[i]);}return 0;
}
(2)希尔排序
不稳定排序
3. 交换类排序
(1)冒泡排序
相邻元素比较和交换,一趟排序后最大移到最右、或最小移到最左。
示例代码:
#include <stdio.h>
int less(int x,int y){return ((x<y)?1:0);
}
int large(int x, int y){return ((x>y)?1:0);
}void bubbleSort(int arr[], int n, int(*compare)(int,int)){int i,j;int swapped =1;for(i=0;swapped;i++){swapped=0;for(j=0;j<n-1;j++){if(compare(arr[j+1],arr[j])){swap(arr[j+1], arr[j]);swapped = 1;}}}
}void bubbleSortTest(){int data1[] = {4,2,6,3,1};bubbleSort(data1, 5, less);for(int i : data1){printf("%d ", i);}
}
int main() {bubbleSortTest();return 0;
}
(2)快速排序
代码:
int qusort(int s[],int start,int end) //自定义函数 qusort()
{int i,j; //定义变量为基本整型i=start; //将每组首个元素赋给ij = end; //将每组末尾元素赋给js[0]=s[start]; //设置基准值while(i<j){while(i<j&&s[0]<s[j])j--; //位置左移if(i<j){s[i]=s[j]; //将s[j]放到s[i]的位置上i++; //位置右移}while(i<j&&s[i]<=s[0])i++; //位置左移if(i<j){s[j]=s[i]; //将大于基准值的s[j]放到s[i]位置j--; //位置左移}}s[i]=s[0]; //将基准值放入指定位置if (start<i)qusort(s,start,j-1); //对分割出的部分递归调用qusort()函数if (i<end)qusort(s,j+1,end);return 0;
}
4. 选择类排序
(1)直接选择排序
void selectSort(int data[], int n){// k 指向最小值的下标int i,j,k;int temp;for(i=0;i<n-1;i++){for(k=i,j=i+1;j<n;j++){if(data[j]<data[k])k=j;if(k!=i){temp = data[i];data[i]=data[k];data[k]=temp;}}}
}
(2) 堆排序
- 大顶堆:越往上越大,父亲节点大于孩子结点;
- 小顶堆:越往下越大,孩子结点大于父亲结点;
5. 归并排序
6. 基数排序
7. 总结
类别 | 排序方法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
插入排序 | 直接插入 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 稳定 |
插入排序 | Shell排序 | O ( n 1.25 ) O(n^{1.25}) O(n1.25) | − - − | O ( 1 ) O(1) O(1) | 不稳定 |
选择排序 | 直接选择排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 不稳定 |
选择排序 | 堆排序 | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( 1 ) O(1) O(1) | 不稳定 |
交换排序 | 冒泡排序 | o ( n 2 ) o(n^2) o(n2) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 稳定 |
交换排序 | 快速排序 | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( n 2 ) O(n^2) O(n2) | O ( l o g 2 n ) O(log_2n) O(log2n) | 不稳定 |
归并排序 | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( n ) O(n) O(n) | 稳定 | |
基数排序 | O ( d ( r + n ) ) O(d(r+n)) O(d(r+n)) | O ( d ( r + n ) ) O(d(r+n)) O(d(r+n)) | O ( r + n ) O(r+n) O(r+n) | 稳定 |
初级程序员软考重点6 数据结构与算法相关推荐
- 初级程序员软考重点7 软件工程
初级程序员软考重点7 软件工程 一.软件工程概述 1. 软件生存周期 2. 软件生成周期模型 (1)瀑布模型(Waterfall Model) 原型模型的概念 (2)演化模型(Evolutionary ...
- 初级程序员软考重点5 程序设计语言
初级程序员软考重点5 程序设计语言 一.程序设计语言及其构成 1. 常见的高级程序语言 2. 通用的程序设计语言 3. 标记语言 二.表达式 1. 表达式的类型及转换规则 示例: 1. a入栈 2. ...
- 程序员软考刷题笔记——软件开发和运行维护基础知识
1. 系统切换费用属于(系统运行维护费用) 2. 文档设计的要点不包括(采用文档模板以减少以后随软件版本的升级而更新文档的工作量) 文档设计的要点包括: 1.编写文档前应先做规划 2.要选择最合适表达 ...
- 程序员到底为什么要掌握数据结构与算法?
周末了,闲聊几句. 当代程序员,也就是我们,其实是非常幸运的,为什么?因为前人,也就是那些大牛已经为你铺好路了. 大牛铺路导致的后果就是整个计算机系统像这个汉堡包一样是分层的: 越是上层越抽象,用起来 ...
- 一般项目中哪里体现了数据结构_优秀程序员都应该学习的数据结构与算法项目(GitHub 开源清单)...
前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 强烈推荐 GitHub 上值得前端学习的数据结构与算法项目,包含 gif ...
- 程序员软考真题__专项:数据结构与算法 02
2.表达式()的结构可用下面的二叉树表示 A. a-(b+c×d) B. a-(b+c)×d C. a-(b×c+d) D. a-(b×(c+d)) 知识点:二叉树存储表达式,左右子树分别代表两个表达 ...
- 2023年软考初级程序员
一.考试科目: 程序员考两科,每科满分75分,45分及格. 科目一选择题:计算机硬软件基础知识,整体来说选题题部分是比较简单的. 科目二主观题:程序设计,下午题为6道大题,满分75分,45分及格.前4 ...
- 软考初级程序员下午题题库
前言 本篇文章包含2005年到2022年,软考初级程序员下午真题,针对个别的题会做一些知识点讲解.答案有错误请评论,我一定会看!每天更新几题,2023.4.9–??祝考试顺利. 2005年下午题 答案 ...
- 软考初级程序员有什么参考的书籍,主要考什么?
软考初级程序员的参考书籍是官方教材--清华大学出版的<程序员教程>,复习的时候买这一本就好了. 主要考哪些知识点可以考试大纲里面的说明,考的其实都是一些基础的计算机知识. 既然是程序员,那 ...
最新文章
- usaco Cowxor (trie 树)
- php微信小程序物流进度推送,微信小程序 消息推送php服务器验证实例详解
- python中x,y=y,x的交换原理
- linux下arp***的解决方案[转]
- 微盟616助力品牌潮出圈背后,智慧零售迈入广阔收获期
- 收集几个移动平台浏览器的User-Agent
- [专栏精选]Unity中的Git最佳实践
- 彩虹屁支持java吗_IDEA版本彩虹屁插件idea-rainbow-fart,一个在你编程时疯狂称赞你的 IDEA扩展插件...
- 【转】计算机人工智能技术纵览---入门部分
- python调用hive与java调用区别_使用Pyhive调用
- 读懂 PetaLinux:让 Linux 在 Zynq 上轻松起“跑”(转)
- Gitlab权限说明
- BL0940电能计量 设计
- java一只母牛 一年生头小牛_Java实现:工厂有一头母牛,一年生一头小母牛,小母牛五年后可以生小牛,问20年工厂有多少头牛?...
- 51 Best DevOps Tools for #DevOps Engineers
- leetcode简单之1677.发票中的产品金额*
- C/C++基于朋友圈的商品推荐系统
- 【渝粤题库】广东开放大学 管理学基础 形成性考核
- c盘清理小技巧(亲测,效果还可以)
- 引起网络广播风暴的原因