插入排序
思路:在此是将数组进行升序排序,把长度为n的数组看做有序的a[0.......n-2]和a[n-1]两部分组成,然后从右到左扫描a[0......n-2]数组,找到第一个小于或等于a[n-1]的元素,然后将a[n-1]插入到,然后把a[n-1]插入到该元素的后面,体现了分治的思想。 该算法最坏情况是一个降序排列的输入,需要经过n*n次比较,最好的情况是一个升序排列的输入,需要比较的次数为n-1次,平均效率也要比冒泡排序和选择排序要好。
#include "stdafx.h"
#include<iostream>
using namespace std;
void InsertSort(int *a,int n) {
int temp;
int j;
for(int i=1;i<n;++i) {
temp=a[i];
j=i-1;
while(j>=0&&a[j]>temp) {
a[j+1]=a[j];
j=j-1;
}
a[j+1]=temp;
}
}
// 函数模板
template<typename T>
void InsertSort(T *arr,const int &n) // arr为存放数据,n 为长度
{
if(0==n||1==n)
return;
for(int i=1;i!=n;++i) {
T curValue=arr[i];
int back=i-1;
while(back>=0&&arr[back]>curValue) {
arr[back+1]=arr[back];
--back;
}
arr[back+1]=curValue;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int num,a[20];
cout<<"输入数据的个数:"<<endl;
cin>>num;
cout<<"依次输入每个数:"<<endl;
for(int i=0;i<num;++i) {
cin>>a[i];
}
InsertSort(a,num);
for(int i=0;i<num;++i) {
cout<<a[i]<<" ";
}
system("pause");
return 0;
}
无向图的深度优先遍历
思路:全局数组visited[] 用来跟踪那些点已经被遍历,算法的效率与用来表示图的数据结构规模成正比,对于邻接矩阵表示法,该遍历的效率为n*n;对于邻接表表示法,效率为(n+e),其中n和e 分别指图的顶点数和边数。深度优先遍历基本应用包括检查图的连通性和无环性等。。
#include "stdafx.h"
#include<iostream>
using namespace std;
#define MAXNUM 30
typedef char vertextype;
typedef int edgetype;
typedef struct Graph{
vertextype vertex[MAXNUM];
edgetype edge[MAXNUM][MAXNUM];
int vernumber;
int edgenumber;
};
int visited[MAXNUM];
int CreateGraph(Graph &gra){
cout<<"输入的顶点的个数和边的条数:"<<endl;
cin>>gra.vernumber>>gra.edgenumber;
cout<<"输入顶点的值"<<endl;
for(int i=0;i<gra.vernumber;++i)
cin>>gra.vertex[i];
for(int i=0;i<gra.vernumber;++i)
for(int j=0;j<gra.vernumber;++j) {
gra.edge[i][j]=0;
}
cout<<"输入每一条边,对每一个顶点从0开始依次编号0 1 2...."<<endl;
for(int i=0;i<gra.edgenumber;++i) {
int temp1,temp2;
cin>>temp1>>temp2;
gra.edge[temp1][temp2]=1;
gra.edge[temp2][temp1]=1;
}
return 1;
}
void DFS(Graph gra,int k) {
cout<<gra.vertex[k]<<"---->";
visited[k]=1;
for(int i=0;i<gra.vernumber;++i) {
if(gra.edge[k][i]=1&&visited[i]!=1)
DFS(gra,i);
}
}
void DFSTraverse(Graph gra,int k) {
for(int i=0;i<gra.vernumber;++i)
visited[i]=0;
DFS(gra,k);
for(int i=0;i<gra.vernumber;++i)
if(visited[i]==0)
DFS(gra,i);
}
int _tmain(int argc, _TCHAR* argv[])
{
Graph gra;
CreateGraph(gra);
DFSTraverse(gra,0);
system("pause");
return 0;
}
无向图的广度优先遍历
思路:与深度优先遍历类似,效率情况也是一样的,不同之处是深度优先是递归调用,应用数据结构”栈“,而广度优先应用了队列 。
#include "stdafx.h"
#include<iostream>
using namespace std;
#define MAXNUM 30
typedef char vertextype;
typedef int edgetype;
typedef struct Graph{
vertextype vertex[MAXNUM];
edgetype edge[MAXNUM][MAXNUM];
int vernumber;
int edgenumber;
};
typedef struct QueueNode{
int vertex;
QueueNode *next;
};
typedef struct Queue{
QueueNode *front;
QueueNode *rear;
};
void InitQueue(Queue &que){
que.front=que.rear=NULL;
}
bool IsEmpty(Queue que) {
if(que.front==NULL&&que.rear==NULL)
return true;
else
return false;
}
void InsertQueue(Queue &que,int vex){
QueueNode*node=(QueueNode *)malloc(sizeof(QueueNode));
node->vertex=vex;
node->next=NULL;
if(IsEmpty(que)) {
que.front=que.rear=node;
}
else {
que.rear->next=node;
que.rear=node;
}
}
int DeleteQueue(Queue &que) {
QueueNode *temp;
int vex;
if(que.rear==que.front==NULL) {
cout<<"队列空了"<<endl;
}
temp=que.front;
vex=temp->vertex;
que.front=que.front->next;
if(que.rear==temp) {
que.rear=NULL;
}
free(temp);
return vex;
}
int visited[MAXNUM];
int CreateGraph(Graph &gra){
cout<<"输入的顶点的个数和边的条数:"<<endl;
cin>>gra.vernumber>>gra.edgenumber;
cout<<"输入顶点的值"<<endl;
for(int i=0;i<gra.vernumber;++i)
cin>>gra.vertex[i];
for(int i=0;i<gra.vernumber;++i)
for(int j=0;j<gra.vernumber;++j) {
gra.edge[i][j]=0;
}
cout<<"输入每一条边,对每一个顶点从0开始依次编号0 1 2...."<<endl;
for(int i=0;i<gra.edgenumber;++i) {
int temp1,temp2;
cin>>temp1>>temp2;
gra.edge[temp1][temp2]=1;
gra.edge[temp2][temp1]=1;
}
return 1;
}
void BFSTraverse(Graph gra,int k){
Queue que;
InitQueue(que);
for(int i=0;i<gra.vernumber;++i)
visited[i]=0;
cout<<gra.vertex[k]<<"--->";
visited[k]=1;
InsertQueue(que,k);
while(!IsEmpty(que)) {
int current;
current=DeleteQueue(que);
for(int i=0;i<gra.vernumber;++i) {
if(gra.edge[current][i]&&visited[i]==0) {
cout<<gra.vertex[i]<<"--->";
visited[i]=1;
InsertQueue(que,i);
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Graph gra;
CreateGraph(gra);
BFSTraverse(gra,0);
system("pause");
return 0;
}
拓扑排序
思路: 找出入度为0的顶点,将其如栈,循环出栈,将其删除(输出),然后将与该点相连的其他的点的入度减一(减治思想),如果减一后入度为0则将其入栈,然后再循环。 当最后栈为空,而输出的点少于有向图中的顶点数时,说明存在环。具体代码如下:
#include "stdafx.h"
#include<iostream>
#include<stack>
using namespace std;
#define MAX 30
typedef struct node{
int vertex;
struct node *next;
};
typedef node nodearray[MAX];
typedef struct Graph{
int vexnum;
int edgenum;
nodearray edge;
int indegree[MAX];
};
int CreateDirGraph(Graph &gra) {
cout<<"输入顶点的个数和边的数量"<<endl;
int vexnum,edgenum;
cin>>vexnum>>edgenum;
gra.vexnum=vexnum;
gra.edgenum=edgenum;
for(int i=0;i<vexnum;++i) {
gra.edge[i].vertex=i;
gra.edge[i].next=NULL;
gra.indegree[i]=0;
}
cout<<"依次输入每一条边:"<<endl;
for(int i=0;i<edgenum;++i) {
int temp1,temp2;
cin>>temp1>>temp2;
node * newnode=NULL;
newnode=(node*)malloc(sizeof(node));
newnode->vertex=temp2;
newnode->next=gra.edge[temp1].next;
gra.edge[temp1].next=newnode;
gra.indegree[temp2]++;
}
return 1;
}
// 拓扑排序的源删除算法
void TopologicSort(Graph gra) {
stack<int> topstack;
int count=0;
int current;
node * thenext=NULL;
for(int i=0;i<gra.vexnum;++i) {
if(gra.indegree[i]==0)
topstack.push(i);
}
while(topstack.size()!=0) {
current=topstack.top();
topstack.pop();
cout<<" "<<current;
count++;
for(thenext=gra.edge[current].next;thenext!=NULL;thenext=thenext->next) {
int k=thenext->vertex;
gra.indegree[k]--;
if(gra.indegree[k]==0)
topstack.push(k);
}
}
cout<<endl;
if(count<gra.vexnum)
cout<<"有回路"<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Graph gra;
CreateDirGraph(gra);
TopologicSort(gra);
system("pause");
return 0;
}
生成排列 最小变化要求
Johnson-Trotter 算法
生成子集算法
格雷码
减治之减常因子算法
假币问题
俄式乘法
约瑟夫斯问题
迭代是反复、 循环执行的意思,根据迭代关系不断更新迭代变量,朝着迭代算法的结束条件循环执行。
递归算法就包含有迭代的意思,不断执行某一个操作,不断更新规模,朝着递归出口不断执行。
二叉查找树的查找和插入
拈游戏
平衡查找树(AVL)
2-3树
快速傅立叶变换