一、回顾
顺序表: | 数组 |
链式表: | 单向链表 双向链表 循环链表 内核链表 |
栈: | 顺序栈 链式栈 |
队列: | 顺序队列、循环队列 链式队列 |
散列结构: | 哈希表: |
二、树型结构
1.定义(一对多):
树:由n个节点组成的有限集有一个根节点;其他节点只有一个前驱节点,但可以有多个后继节点。
根:无前驱,有后继n=0,空树
叶子结点(终端结点):有前驱结点、无后继结点
分支结点(非终端结点):有前驱结点,有后继结点
度:
深度:树的层数
广度:树中最大结点的度就是树的广度
结点的度:当前结点的后继结点个数
二叉树:树的度为二,且左右子树不可交换位置
满二叉树:在不增加层数的前提下,无法再增加一个结点
满二叉树第K层结点个数:2^(K-1)
K层满二叉树结点总个数:2^K-1
完全二叉树:在满二叉树的前提下,增加数据只能从上到下、从左至右;
删除数据只能从下至上,从右向左。
满二叉树->完全二叉树
完全二叉树 !-> 满二叉树
2.遍历
(广度优先遍历算法)
前序遍历:根左右
中序遍历:左根右
后序遍历:左右根
(深度优先遍历算法)
层遍历:从上到下,从左到右,逐层遍历
*已知前序+中序才能还原出唯一的二叉树
#include<stdio.h>
#include"tree.h"
#include"queue.h"
#include<stdlib.h>
//正序遍历的结果
char tr[]={"ABDH##IJ###E##CF##G##"};
int ipt;
//创建二叉树
Tree_node *creat_tree()
{
Data_type d = tr[ipt++];
if('#'==d)
{
return NULL;
}
Tree_node *tree = malloc(sizeof(Tree_node));
if(NULL ==tree)
{
printf("fail creat");
return NULL;
}
tree->data = d;
tree->pl = creat_tree();
tree->pr = creat_tree();
return tree;
}
//正序遍历
void tree_for_each1(Tree_node*tree)
{
if(NULL==tree)
{
return;
}
printf("%c",tree->data);
tree_for_each1(tree->pl);
tree_for_each1(tree->pr);
}
//中序遍历
void tree_for_each2(Tree_node*tree)
{
if(NULL==tree)
{
return;
}
tree_for_each2(tree->pl);
printf("%c",tree->data);
tree_for_each2(tree->pr);
}
//逆序遍历
void tree_for_each3(Tree_node*tree)
{
if(NULL==tree)
{
return;
}
tree_for_each3(tree->pl);
tree_for_each3(tree->pr);
printf("%c",tree->data);
}
//节点数
void num_tree_node(Tree_node*tree,int*num)
{
if(NULL!=tree)
{
(*num)++;
num_tree_node(tree->pl,num);
num_tree_node(tree->pr,num);
}
return ;
}
//销毁
void destroy_tree(Tree_node*tree)
{
if(NULL==tree)
{
return ;
}
Tree_node *delt = tree;
destroy_tree(delt->pl);
destroy_tree(delt->pr);
free(delt);
}
//树的层数
void level_of_tree(Tree_node*tree,int*level)
{
if(NULL==tree)
{
return ;
}
(*level)++;
int mid1 = *level;
int mid2 = *level;
level_of_tree(tree->pl,&mid1);
level_of_tree(tree->pr,&mid2);
*level = mid2>mid1?mid2:mid1;
}
void level_for_each(Tree_node*tree)
{
if(NULL==tree)
{
return ;
}
Queue *qu=create_queue();
enter_queue(qu,tree);
printf("%c",tree->data);
while(!is_empty_queue(qu))
{
if(qu->pfront->pdata->pl)
{
enter_queue(qu,qu->pfront->pdata->pl);
printf("%c",qu->pfront->pdata->pl->data);
}
if(qu->pfront->pdata->pr)
{
enter_queue(qu,qu->pfront->pdata->pr);
printf("%c",qu->pfront->pdata->pr->data);
}
out_queue(qu,NULL);
}
destroy_queue(&qu);
puts("");
}
三、算法:解决特定问题的求解步骤
如何衡量算法优越
算法的设计
1.正确性.
语法正确
合法的输入能得到合理的结果。
对非法的输入,给出满足要求的规格说明
对精心选择,甚至习难的测试都能正常运行,结果正确
2.可读性
便于交流,阅读,理解高内聚 低耦合
3.健壮性
输入非法数据,能进行相应的处理,而不是产生异常
4.高效率(时间复杂度)
时间复杂度:数据增长量与处理时间的关系
时间复杂度的计算规则
1,用常数1 取代运行时间中的所有加法常数
2、在修改后的运行医数中,只保留最高阶项
3、如果最高阶存在且系数不是1,则去除这个项相乘的常/数。
5.低存储(空间复杂度)
四、算法回顾
排序算法:
1. 思想:实现过程
2. 代码
3. 时间复杂度
4. 排序算法的稳定性:对于两个相同的数据,经过排序,两个相同数据的相对位置没有
发生变化,这就是一个稳定的排序算法。
冒泡排序:相邻两两比较,优先排好最大值
for(i=len-1;i>0;--i)
{
for(j=0;j<i;++j)
{
if(a[i]>a[j])
{
swap(a[i],a[j]);
}
}
}
时间复杂度:O(n^2)
稳定性:稳定
选择排序:将待排位置的数据和后续的数据依次进行比较,将小的存放在待排位置,
经过一趟,优先排好最小值。
for(int i = 0; i < len-1; i++)
{
for (int j = i+1,; j < len; j++)
{
if (a[i] > a[j])
swap(a[i], a[j]);
}
}
时间复杂度:O(n^2)
稳定性:不稳定
插入排序: 将待排的元素,依次插入到一个有序序列中,确保插入后任然有序。
for(int i = 0; i < len-1; i++)
{
for (int j = i+1,; j < len; j++)
{
if (a[i] > a[j])
swap(a[i], a[j]);
}
}
时间复杂度:O(n^2)
稳定性:稳定
快速排序:选定基准值,从两头分别和基准值比较,比基准值大的向后,比基准值小的向前,优先排好基准值。
void Qsort(int *begin, int *end)
{
int *p = begin;
int *q = end;
if(begin >= end)
{
return ;
}
int t = *begin;
while(p < q)
{
while(p < q && *q >= t)
{
--q;
}
while(p < q && *p <= t)
{
++p;
}
swap(p, q);
}
swap(begin, p);
Qsort(begin, p - 1);
Qsort(p + 1, end);
}
时间复杂度:O(nlogn)
稳定性:不稳定
希尔排序:将待排的序列,按照增量分成若干个子系列,对子序列进行插入排序。
void shell_sort(int *a, int len)
{
int j = 0;
for (int inc = len/2; inc > 0; inc /=2)
{
for (int i = inc; i < len; i++)
{
j = i;
int tmp = a[i];
while (j >= inc && a[j-inc] > tmp)
{
a[j] = a[j-inc];
j = j-inc;
}
a[j] = tmp;
}
}
}
时间复杂度:O(nlogn)-O(n^2)
稳定性:不稳定
二分查找:
前提:有序的序列
int BinaryFind(int a[],int len,int n)
{
int begin=0;
int end=len-1;
int mid;
while(begin<=end)
{
mid=(begin+end)/2;
if(n<a[mid])
{
end=mid-1;
}
else if(n>a[mid])
{
begin=mid+1;
}
else
{
break;
} }
if(begin<=end)
{
return mid;
}
else
{
return -1;
}
}
时间复杂度:O(logn)