常见排序
插入类排序
直接插入排序
算法思想:将第i个记录插入到第i-1个已经排好的记录中,从i=2开始;关键字ki与前面记录ki-1,ki-2,……,k1进行比较,大于ki的记录依次向后移动一个位置,直到遇到小于等于ki的kj,kj后面为空,则插入
折半插入排序
算法思想:在有序记录r[1,2,……,i-1]中确定应插入的位置;
x.key<r[mid].key high = mid-1,左插;
x.key>r[mid].key low = mid+1,右插;
希尔排序
算法思想:对初始关键字序列,每次分别取d1,d2,d3……dn=1的间隔进行排序,将所有间隔为di的分为一组,进行组内排序
交换类排序
冒泡排序
算法思想:通过对相邻元素进行交换,顺次比较相邻的两个元素的大小,若a[i] > a[i+1],t = a[i+1] ,a[i+1] = a[i] ,a[i] = t;
快速排序
算法思想:将r[low]置为空单元;high从右向左扫描,若r[high].key < x.key时,r[high]移至空单元r[low]中,此时r[high]为空单元。
low从左向右扫描,若r[low].key > x.key,将r[low]移至r[high]空单元,此时r[low]为空单元;一直重复上述步骤,直至low = high时一趟快速排序结束。
选择类排序
简单选择排序
算法思想:i指向下一个最小元素应该出现的位置,k指向下一个最小元素(每次找出剩余元素中最小的元素,重复此步骤)
堆排序
大顶堆:arr[i]>=arr[2i+1] && arr[i]>=arr[21+2]
小顶堆:arr[i]<=arr[2i+1] && arr[i]<=arr[21+2]
算法思想:构建初始堆,将无序序列构建成堆(大顶堆或者小顶堆);将堆顶元素与末尾元素进行交换,将最大元素“沉”到数组末端;重新调整剩余元素,重复上述两个步骤,直到整个序列有序
归并排序
算法思想:将两个或者两个以上有序表合并成一个新的有序表
顺序表和链表
线性表的顺序存储
线性表的顺序存储——一组地址连续的存储单元依次存储
1)查找
①按序号查。表中元素在L的elem数组中顺序存放。L.elem[i-1]
②按内容(e)查找L中与给定值相等的数据元素。 L.elem[i] == e return(i+1)
2)插入
①表尾插入,i=n+1,直接插入,表长度为n+1
②表中插入,将n,n-1,……,i上的结点依次后移至n+1,n,……,i+1,将元素插入第i个位置上
3)删除
①表尾删除,i=n直接删,表长度变为n-1
②表中删除,将i+1,i+2……,n向前依次移至i,i+1……,n-1,将第i个元素删除
线性表的链式存储
逻辑上相邻的元素其存储的物理位置也是相邻的
链表存储有单链表,循环列表,双向链表
单链表:
每个结点只有一个next指针域(只能向后)
第一个结点无前驱,最后一个结点没有直接后继,指针域为“NULL”
头插法和尾插法建立单链表
1)查找
①按序号查 从头指针出发,顺序域next逐个结点向下搜索,直至搜索到第i个结点
{p = p->next;j++;if(i == j) return p}返回第i个结点的地址
②按值查(key)
{if(p->data != key) p = p->next;else break;return p}找到key时退出
2)链表长度
从头开始(p = L->next),直到最后结点(p->next == NULL) return j;
3)插入
三步走,查找。找到第i-1个结点,由指针pre指示
申请。申请新的结点s,将其数据域置为e
插入。P->next = s; s->nest = p->nest
将s赋给前驱的后继
将前驱的后继赋给s的后继
尾部插入 pre->next = s; s->nest = NULL;
4)删除
二步走:查,找到第i-1个结点并由指针pre指示,r = pre->next
删:pre->next = r->next;free®
尾删 r = pre->next
Pre->next = NULL;free®
双向链表
1)插入四步走:
①s->prior = p->prior
②p->prior->next = s
③s->next = p
④p->prior = s
尾插:
s->prior = p
P->next = s
S->next = NULL
2)删除操作
①p->prior->next = p->next
②p->next->prior = p->prior
树的遍历
先序遍历:
root;
root->LChild;
root->RChild;(根、左、右)
中序遍历:
root->LChild;
root;
root->RChild(左、根、右)
后序遍历:
root->LChild;
root->RChild;
root(左、右、根)
先序遍历结果:A ,B ,D ,F ,G ,C ,E ,H
中序遍历结果:B ,F ,D ,G ,A ,C ,E ,H
后序遍历结果:F ,G ,D ,B ,H ,E ,C ,A
图
1.有n(n-1)/2条边的无向图为无向完全图
2.第一个顶点和最后一个顶点相同,v=v’,该路径为一个回路或环
3.图中任意两点连通,则该无向图G为连通图
图的遍历
图的深度优先遍历(DFS)递归支撑
首先寻找第一个起始顶点v0
V0的第一个未被访问的邻接点,然后访问该顶点。重复此步骤,直到刚访问过的顶点没有未被访问的邻接点
返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点下一个未被访问的邻接点。
即一直向下访问,直至该点没有,向上返回,直至一个点有未被访问的邻接点
图的广度优先遍历(BFS)队列支撑
首先寻找第一个起始顶点v0
依次访问v0各个未被访问的邻接点
分别从这些邻接点出发,依次访问她们各个未被访问的邻接点
最小生成树
普利姆算法:
选择顶点,按照顶点邻接最小边选择新的顶点
克鲁斯卡尔算法:
每次选择最小边,生成不闭环的图
关键路径
入度为0的顶点,为源点。出度为0的点,为汇点。
从源点到汇点的最长路径(完成整个工程任务所需时间)该路径称为关键路径,关键路径上的活动称为关键活动。
最短路径
迪杰斯特拉算法:
从V0到各个终点dist[i]和path[i]变化,某一顶点到其他各顶点的最短路径,每次取得最短路径结点,下次在剩余结点中选最短路径
弗洛伊德算法:
任意一对顶点间的最短路径(邻接矩阵表示),每一对顶点间最短路径