算法设计与分析 chapter(1-2)复习

根据期末老师划的重点复习…=_=!

1 算法概念:

  • 算法是解决问题的一种方法或一个过程,更严格的讲算法是由若干指令组成的又穷序列

2 算法特征:

  • 输入:有0个或多个输入
  • 输出:至少有1个输出
  • 确定性:组成算法的指令必须清晰无歧义
  • 有限性:每条指令执行的次数有限,时间也必须有限

3 分治法基本思想:

将一个规模为n的问题,分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归地解决这些子问题,然后将各个子问题的解合并得到原问题的解。


4 分治法基本步骤:

分治法在每一层递归上都有三个步骤:

  • 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
  • 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题;
  • 合并:将各个子问题的解合并为原问题的解。

5 递归汉诺塔问题(递归):

  • 算法思想
    利用递归的算法思想,
    若n=1直接可以将a上的移动到b
    若n>1的话按以下下步骤:
    首先设法将a上的n-1个圆盘移动到c han(a—c---b)
    然后将a上的最后一个圆盘移动到b move(a,b)
    再次将c上的n-1照以上方式将圆盘移动到b han(c—b---a)
  • 时间复杂度:O(2^n)
  • 代码
#include<iostream>
using namespace std;
int count=0;
void move(char a,char c){
	cout<<a<<"---->"<<c<<endl;
	count++;
}
//##########核心代码区域#############/
void hannuo(int n,char a,char b,char c){
	if(n>0){
		hannuo(n-1,a,c,b);
		move(a,b);
		hannuo(n-1,c,b,a);
	}
}
int main(){
	char a,b,c;
	a = 'A';
	b = 'B';
	c = 'C';	
 	hannuo(4,a,b,c);
 	cout<<"移动的步骤:"<<count<<endl;
 	return 0;	
}

6 二分搜索算法(分治):

  • 算法思想
    将n个元素分成个数大致相同的两半,取a[n/2]与x比较
    如果找到,则终止
    如果x<a[n/2] 则只在数组a的左半部继续搜索x
    如果x>a[n/2] 则只在数组a的右半部继续搜索x
  • 算法时间
    最坏的时间:while循环执行O(logn)次 循环内执行O(1)次,整个算法时间是:O(logn)
  • 算法代码
#include<iostream>
using namespace std;
//数组,查找数x,数组的长度 
int BinarySearch(int a[],int x,int n){
	int left=0;
	int right=n-1;
	while(left<=right){
		int mid = (left+right)/2;
		if(x == a[mid]) return mid;
		else if(x>a[mid]) left = mid+1;
		else right = mid-1;
	} 
	return -1;
}
int main(){
	int a[8]={1,2,3,4,5,6,7,8};
	int index;
	index = BinarySearch(a,4,8);
	cout<<"数组下标index="<<index<<endl;
	return 0; 
}

7 合并排序和快速排序算法(分治):

  • 算法思想
    合并排序的思想:将待排序的元素分成大小大致相同的两个子集和,分别对两个子集排序,最终将排序好的子集合并成要求的排好序的集合
    快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。:
  • 算法时间
    合并排序:O(nlogn)
    快速排序:
    最坏情况:O(n^2)
    最好情况:O(nlogn)
    平均时间复杂度:O(nlogn)
  • 算法代码

//合并排序//

//合并排序//
#include<iostream>
using namespace std;
void MergeSort(int a[],int left,int right,int c[]);
void Merge(int left,int mid,int right,int c[],int a[]);
int main(){
	int a[10] = {1,3,5,6,4,2,7,9,8,0};
	int c[10] = {0};
	MergeSort(a,0,10,c);
	for(int i=0;i<10;i++){
		cout<<a[i]<<",";
	}
	return 0;
} 
void MergeSort(int a[],int left,int right,int c[]){
	if(left<right){
		int mid=(left+right)/2;
		MergeSort(a,left,mid,c); //左边合并排序 
		MergeSort(a,mid+1,right,c);//右边合并排序 
		Merge(left,mid,right,c,a); //将排序好的子集合并到数组b 
	}
}
void Merge(int left,int mid,int right,int c[],int a[]){
	int i = left; //左序列指针 
	int j = mid+1; //右序列指针 
	int t = 0; // c数组指针 
	while(i<=mid && j<=right){
		if(a[i]<=a[j]){
			c[t++] = a[i++];
		}
		else{
			c[t++] = a[j++];
		}
	}
	while(i<=mid)	c[t++] = a[i++]; //将左边剩余元素填充进c中 
	while(j<=right)	c[t++] = a[j++]; //将右边剩余元素填充进c中 
	t = 0;
	//将c中元素拷贝到a中 
	while(left<=right) a[left++]=c[t++];
} 

//快速排序//

//快速排序//
#include<iostream>
using namespace std;
void quickSort(int a[],int left,int right){
	int i = left;
	int j = right;
	int t=0;
	if(i<j){ //待排序的元素至少有两个的情况
		t = a[i]; //待排序的第一个元素作为基准元素
		while(i != j){ //从左右两边交替扫描,直到i = j
			while(j>i && a[j]>=t)
				j--;  //从右往左扫描,找到第一个比基准元素小的元素
				a[i] = a[j];//找到这种元素a[j]后与a[i]交换
			
			while(i<j && a[i]<=t)
				i++;  //从左往右扫描,找到第一个比基准元素大的元素
				a[j] = a[i];//找到这种元素arr[left]后,与arr[right]交换
		}
		a[j] = t; //基准元素归位
		quickSort(a,left,i-1); //对基准元素左边的元素进行递归排序
		quickSort(a,j+1,right); //对基准元素右边的元素进行递归排序
	}
}
int main(){
	int a[10] = {1,3,5,6,4,2,7,9,8,0};
	quickSort(a,0,9); //传递的长度是n-1
	for(int i=0;i<10;i++){
		cout<<a[i]<<",";
	}
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值