《算法设计与分析》教案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Perm(a,0,3);
}
第4章分治法
4.1 合并排序
void Merge(int a[], int b[], int l, int m, int n)
{ //将a[l]…a[m]和a[m+1]…a[n]合并到b[l]…b[n]
int i=l, j=m+1, k=l;
while(i<=m && j<=n)
有n件工作要分配给n个人去完成,将工作i分配给第j个人所需的费用为Cij,找出总成本最小的分配方案。
补充例题
1、数字全排列(直接的方法)
int main()
{ int a[4]={1,2,3,4},m[4];
for(int i1=0;i1<4;i1++)
{ m[0]=a[i1];
for(int i2=0;i2<4;i2++)
for(int k=0;k<4;k++) cout<<m[k]<<" ";
cout<<endl;
}
}
}
}
}
2、数字全排列(使用STL)
#include<iostream>
#include<algorithm>
using namespace std;
const int n=4;
int main()
{
int a[4]={2,4,3,1};
{ m[1]=a[i2];
if(m[1]==m[0])continue;
for(int i3=0;i3<4;i3++)
{ m[2]=a[i3];
if(m[2]==m[1] || m[2]==m[0])continue;
for(int i4=0;i4<4;i4++)
{ m[3]=a[i4];
if(m[3]==m[0] || m[3]==m[1] || m[3]==m[2])continue;
if(l==r-1)
{ if(a[l]>a[r]) { max=a[l]; min=a[r]; }
else { max=a[r]; min=a[l]; }
return;
}
int m = (l+r)/2;
T max1,max2,min1,min2;
MaxMin(a, l, m, max1, min1);
else { max=a[1]; min=a[0]; }
int i;
for(i=2; i<n-1; i+=2)
{ if(a[i]>a[i+1])
{ if(a[i]>max) max=a[i];
if(a[i+1]<min) min=a[i+1];
}
else
{ if(a[i+1]>max) max=a[i+1];
课程的性质和任务:
本课程是计算机科学与技术专业的专业必修课。本课程旨在培养学生分析问题和解决问题的能力,使学生掌握算法设计的基本方法,熟悉算法分析的基本技术,并能熟练运用一些常用算法,为学生进一步学习奠定良好的基础。本课程着重于培养学生的算法设计与分析能力,程序设计和实现能力。
教学目的与要求:
学习掌握几种基本的算法:减治法、分治法、动态规划、贪心法、回溯法、分支限界法;掌握算法设计的基本思想和策略、算法优化的技巧、算法性能分析的方法;
sort(a,a+n);
do
{ for(int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
} while(next_permutation(a,a+n));
}
3、数字全排列(递归方法)
template <class T>
void Perm(T a[],int k,int m)
for(i=0; i<=n-m; i++)
{ int j=0;
while(j<m && p[j]==t[i+j])
{ j++;
if(j==m) return i;
}
}
return -1;
}
3.3 最近对和凸包问题的蛮力算法
1、最近对问题
最近对问题要求找出一个包含n个点的集合中距离最近的两个点。
2、凸包问题
if(a[i]<min) min=a[i];
}
}
if(i<n)
{ if(a[i]>max) max=a[i];
if(a[i]<min) min=a[i];
}
}
例:棋盘覆盖问题
#include <iostream>
#include <iomanip>
using namespace std;
int tile; //L型骨牌编号
对于平面上n个点的集合,它的凸包就是包含所有这些点的最小凸多边形。
3.4 穷举查找
1、旅行商问题
一个旅行商到n个城市去进行销售,找出一条代价最小的周游路线。
2、背包问题
给定n个物品和一个背包,物品i的重量为wi,其价值为v1i,背包的承重为W,应如何选择物品,使得装入背包中物品的总价值最大。
3、分配问题
例:在n个元素中找最大值
template<class T>
int Max(T a[], int l, int r)
{
if(l==r) { return a[l]; }
int m = (l+r)/2;
T max1,max2;
max1 = Max(a, l, m);
max2 = Max(a, m+1, r);
MaxMin(a, m+1, r, max2, min2);
max = max1>max2 ? max1 : max2;
min = min1<min2 ? min1 : min2;
}
int main()
{
const int N=20;
int a[N], i, max, min;
srand(time(0));
while(i<n && a[i]!=k) i++;
if(i<n) return i;
else return -1;
}
2、蛮力字符串匹配
给定一个n个字符组成的串,称为文本,一个m个字符的串,称为模式,从文本中寻找匹配模式的串。
int StringMatch(char *t, char *p)
{
int n=strlen(t), m=strlen(p);
if(dr < tr+s && dc < tc+s)
Cover(tr,tc,dr,dc,s);
else
{ Board[tr+s-1][tc+s-1]=t;
Cover(tr,tc,tr+s-1,tc+s-1,s);
}
//处理右上角子棋盘
if(dr < tr+s && dc >= tc+s)
Cover(tr,tc+s,dr,dc,s);
《算法设计与分析》课程教案
课程编号:08051100
课程名称:算法设计与分析(The Design and Analysis of Computer Algorithms)
学时:72学时,其中理论学时54,上机学时18
学分:3.5
开课部门:数学与计算机科学学院
开课教研室:计算机科学
开课教师:雷小园
开课学期:第5学期
}
3.2 顺序查找和蛮力字符串匹配
1、顺序查找
int Search(int a[], int n, int k)
{
for(int i=0; i<n; i++)
if(a[i]==k) return i;
return -1;
}
int Search(int a[], int n, int key)
{
int i=0;
if(a[j] <a[m])m= j; }
swap(a[i],a[m]);
}
}
2、冒泡排序
void bubble(int a[], int n)
{ int i,j,t;
for(i=0; i<n-1; i++)
for(j=0; j<n-i-1; j++)
if( a[j]>a[j+1] )swap(a[j],a[j+1]);
for(i=0; i<N; i++) a[i] = rand() % 1000;
for(i=0; i<N; i++) cout<<a[i]<<" ";
cout<<endl;
MaxMin(a,0,N-1,max,min);
cout<<"max="<<max<<", min="<<min<<endl;
}
{
if(k==m)
{ for(int i=0;i<=m;i++) cout<<a[i]<<" ";
cout<<endl;
}
else
for(int i=k;i<=m;i++)
{ swap(a[k],a[i]);
Perm(a,k+1,m);
swap(a[k],a[i]);
}
}
int main()
{ int a[4]={1,2,3,4};
教学方法:
主要板书讲解算法、程序,辅助多媒体演示程序的运行,上机练习算法编程。
第3章 蛮力法
3.1 选择排序和冒泡排序
1、选择排序
void SelectSort(int a[], int n)
{
int i,j,k,m;
for(i=0; i<n-1; i++)
{ m =i;
for(j=i+1; j<n; j++)
if(a[i]<=a[j]) b[k++] = a[i++];
else b[k++] = a[j++];
while(i<=m) b[k++] = a[i++];
while(j<=n) b[k++] = a[j++];
}
void Msort( int a[], int b[], int s, int t )
例:在n个元素中找最大值和最小值(非递归程序)
template<class T>
void MaxMin(T a[], int n, T& max, T&min)
{
if(n==1) { max=min=a[0]; return; }
if(a[0]>a[1]) { max=a[0]; min=a[1]; }
}
//处理右下角子棋盘
if(dr >= tr+s && dc >= tc+s)
Cover(tr+s,tc+s,dr,dc,s);
else
{ Board[tr+s][tc+s]=t;
Cover(tr+s,tc+s,tr+s,tc+s,s);
}
}
int main()
{
int x,y; //阶数及特殊点位置
int i,j,n; //棋盘规模为 n*n
cin>>n>>x>>y; //读入阶数k和特殊方格位置
//在堆内存中建立棋盘数组,填充特殊方格
Board=new int*[n];
for (i=0;i<n;i++ ) Board[i]=new int[n];
for(int i=s; i<=t; i++) a[i] = b[i];
}
void MergeSort(int a[], int n)
{
int b[n];
Msort(a, b, 0, n-1);
}
4.2快速排序
4.3折半查找
4.4二叉树遍历及其相关特性
4.5大整数乘法和Strassen矩阵乘法
4.6用分治法解决最近对问题和凸包问题
Leabharlann Baidu授课班级:05计科
先修课程:C++语言程序设计、数据结构
考核要求:考试,平时10%,实验20%,考试70%
使用教材:
《算法设计与分析基础(第2版)》,潘彦[译],清华大学出版社,2006年
参考教材:
《算法设计与分析》,吕国英主编,清华大学出版社,2005年
《计算机算法设计与分析(第二版)》,王晓东主编,电子工业出版社,2004年
else
{ Board[tr+s-1][tc+s]=t;
Cover(tr,tc+s,tr+s-1,tc+s,s);
}
//处理左下角子棋盘
if(dr >= tr+s && dc < tc+s)
Cover(tr+s,tc,dr,dc,s);
else
{ Board[tr+s][tc+s-1]=t;
Cover(tr+s,tc,tr+s,tc+s-1,s);
if(max1>max2) return max1;
else return max2;
}
例:在n个元素中找最大值和最小值
template<class T>
void MaxMin(T a[], int l, int r, T &max, T &min)
{
if(l==r)
{ max = min = a[l]; return; }
int **Board;
void Cover(int tr,int tc,int dr,int dc,int size) //棋盘覆盖函数
{
if(size==1) return; //如果棋盘规模=1,返回
int s=size/2; //分割棋盘
int t=++tile; //L型骨牌编号加1
//处理左上角子棋盘
{ // 将a[s..t]进行2-路归并排序,利用b数组。
if (s==t) return;
int m = (s+t)/2; // 将a[s..t]平分为a[s..m]和a[m+1..t]
Msort(a, b, s, m);
Msort(a, b, m+1, t);
Merge(a, b, s, m, t); // 将a[s..m]和a[m+1..t]归并到b[s..t]
}
第4章分治法
4.1 合并排序
void Merge(int a[], int b[], int l, int m, int n)
{ //将a[l]…a[m]和a[m+1]…a[n]合并到b[l]…b[n]
int i=l, j=m+1, k=l;
while(i<=m && j<=n)
有n件工作要分配给n个人去完成,将工作i分配给第j个人所需的费用为Cij,找出总成本最小的分配方案。
补充例题
1、数字全排列(直接的方法)
int main()
{ int a[4]={1,2,3,4},m[4];
for(int i1=0;i1<4;i1++)
{ m[0]=a[i1];
for(int i2=0;i2<4;i2++)
for(int k=0;k<4;k++) cout<<m[k]<<" ";
cout<<endl;
}
}
}
}
}
2、数字全排列(使用STL)
#include<iostream>
#include<algorithm>
using namespace std;
const int n=4;
int main()
{
int a[4]={2,4,3,1};
{ m[1]=a[i2];
if(m[1]==m[0])continue;
for(int i3=0;i3<4;i3++)
{ m[2]=a[i3];
if(m[2]==m[1] || m[2]==m[0])continue;
for(int i4=0;i4<4;i4++)
{ m[3]=a[i4];
if(m[3]==m[0] || m[3]==m[1] || m[3]==m[2])continue;
if(l==r-1)
{ if(a[l]>a[r]) { max=a[l]; min=a[r]; }
else { max=a[r]; min=a[l]; }
return;
}
int m = (l+r)/2;
T max1,max2,min1,min2;
MaxMin(a, l, m, max1, min1);
else { max=a[1]; min=a[0]; }
int i;
for(i=2; i<n-1; i+=2)
{ if(a[i]>a[i+1])
{ if(a[i]>max) max=a[i];
if(a[i+1]<min) min=a[i+1];
}
else
{ if(a[i+1]>max) max=a[i+1];
课程的性质和任务:
本课程是计算机科学与技术专业的专业必修课。本课程旨在培养学生分析问题和解决问题的能力,使学生掌握算法设计的基本方法,熟悉算法分析的基本技术,并能熟练运用一些常用算法,为学生进一步学习奠定良好的基础。本课程着重于培养学生的算法设计与分析能力,程序设计和实现能力。
教学目的与要求:
学习掌握几种基本的算法:减治法、分治法、动态规划、贪心法、回溯法、分支限界法;掌握算法设计的基本思想和策略、算法优化的技巧、算法性能分析的方法;
sort(a,a+n);
do
{ for(int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
} while(next_permutation(a,a+n));
}
3、数字全排列(递归方法)
template <class T>
void Perm(T a[],int k,int m)
for(i=0; i<=n-m; i++)
{ int j=0;
while(j<m && p[j]==t[i+j])
{ j++;
if(j==m) return i;
}
}
return -1;
}
3.3 最近对和凸包问题的蛮力算法
1、最近对问题
最近对问题要求找出一个包含n个点的集合中距离最近的两个点。
2、凸包问题
if(a[i]<min) min=a[i];
}
}
if(i<n)
{ if(a[i]>max) max=a[i];
if(a[i]<min) min=a[i];
}
}
例:棋盘覆盖问题
#include <iostream>
#include <iomanip>
using namespace std;
int tile; //L型骨牌编号
对于平面上n个点的集合,它的凸包就是包含所有这些点的最小凸多边形。
3.4 穷举查找
1、旅行商问题
一个旅行商到n个城市去进行销售,找出一条代价最小的周游路线。
2、背包问题
给定n个物品和一个背包,物品i的重量为wi,其价值为v1i,背包的承重为W,应如何选择物品,使得装入背包中物品的总价值最大。
3、分配问题
例:在n个元素中找最大值
template<class T>
int Max(T a[], int l, int r)
{
if(l==r) { return a[l]; }
int m = (l+r)/2;
T max1,max2;
max1 = Max(a, l, m);
max2 = Max(a, m+1, r);
MaxMin(a, m+1, r, max2, min2);
max = max1>max2 ? max1 : max2;
min = min1<min2 ? min1 : min2;
}
int main()
{
const int N=20;
int a[N], i, max, min;
srand(time(0));
while(i<n && a[i]!=k) i++;
if(i<n) return i;
else return -1;
}
2、蛮力字符串匹配
给定一个n个字符组成的串,称为文本,一个m个字符的串,称为模式,从文本中寻找匹配模式的串。
int StringMatch(char *t, char *p)
{
int n=strlen(t), m=strlen(p);
if(dr < tr+s && dc < tc+s)
Cover(tr,tc,dr,dc,s);
else
{ Board[tr+s-1][tc+s-1]=t;
Cover(tr,tc,tr+s-1,tc+s-1,s);
}
//处理右上角子棋盘
if(dr < tr+s && dc >= tc+s)
Cover(tr,tc+s,dr,dc,s);
《算法设计与分析》课程教案
课程编号:08051100
课程名称:算法设计与分析(The Design and Analysis of Computer Algorithms)
学时:72学时,其中理论学时54,上机学时18
学分:3.5
开课部门:数学与计算机科学学院
开课教研室:计算机科学
开课教师:雷小园
开课学期:第5学期
}
3.2 顺序查找和蛮力字符串匹配
1、顺序查找
int Search(int a[], int n, int k)
{
for(int i=0; i<n; i++)
if(a[i]==k) return i;
return -1;
}
int Search(int a[], int n, int key)
{
int i=0;
if(a[j] <a[m])m= j; }
swap(a[i],a[m]);
}
}
2、冒泡排序
void bubble(int a[], int n)
{ int i,j,t;
for(i=0; i<n-1; i++)
for(j=0; j<n-i-1; j++)
if( a[j]>a[j+1] )swap(a[j],a[j+1]);
for(i=0; i<N; i++) a[i] = rand() % 1000;
for(i=0; i<N; i++) cout<<a[i]<<" ";
cout<<endl;
MaxMin(a,0,N-1,max,min);
cout<<"max="<<max<<", min="<<min<<endl;
}
{
if(k==m)
{ for(int i=0;i<=m;i++) cout<<a[i]<<" ";
cout<<endl;
}
else
for(int i=k;i<=m;i++)
{ swap(a[k],a[i]);
Perm(a,k+1,m);
swap(a[k],a[i]);
}
}
int main()
{ int a[4]={1,2,3,4};
教学方法:
主要板书讲解算法、程序,辅助多媒体演示程序的运行,上机练习算法编程。
第3章 蛮力法
3.1 选择排序和冒泡排序
1、选择排序
void SelectSort(int a[], int n)
{
int i,j,k,m;
for(i=0; i<n-1; i++)
{ m =i;
for(j=i+1; j<n; j++)
if(a[i]<=a[j]) b[k++] = a[i++];
else b[k++] = a[j++];
while(i<=m) b[k++] = a[i++];
while(j<=n) b[k++] = a[j++];
}
void Msort( int a[], int b[], int s, int t )
例:在n个元素中找最大值和最小值(非递归程序)
template<class T>
void MaxMin(T a[], int n, T& max, T&min)
{
if(n==1) { max=min=a[0]; return; }
if(a[0]>a[1]) { max=a[0]; min=a[1]; }
}
//处理右下角子棋盘
if(dr >= tr+s && dc >= tc+s)
Cover(tr+s,tc+s,dr,dc,s);
else
{ Board[tr+s][tc+s]=t;
Cover(tr+s,tc+s,tr+s,tc+s,s);
}
}
int main()
{
int x,y; //阶数及特殊点位置
int i,j,n; //棋盘规模为 n*n
cin>>n>>x>>y; //读入阶数k和特殊方格位置
//在堆内存中建立棋盘数组,填充特殊方格
Board=new int*[n];
for (i=0;i<n;i++ ) Board[i]=new int[n];
for(int i=s; i<=t; i++) a[i] = b[i];
}
void MergeSort(int a[], int n)
{
int b[n];
Msort(a, b, 0, n-1);
}
4.2快速排序
4.3折半查找
4.4二叉树遍历及其相关特性
4.5大整数乘法和Strassen矩阵乘法
4.6用分治法解决最近对问题和凸包问题
Leabharlann Baidu授课班级:05计科
先修课程:C++语言程序设计、数据结构
考核要求:考试,平时10%,实验20%,考试70%
使用教材:
《算法设计与分析基础(第2版)》,潘彦[译],清华大学出版社,2006年
参考教材:
《算法设计与分析》,吕国英主编,清华大学出版社,2005年
《计算机算法设计与分析(第二版)》,王晓东主编,电子工业出版社,2004年
else
{ Board[tr+s-1][tc+s]=t;
Cover(tr,tc+s,tr+s-1,tc+s,s);
}
//处理左下角子棋盘
if(dr >= tr+s && dc < tc+s)
Cover(tr+s,tc,dr,dc,s);
else
{ Board[tr+s][tc+s-1]=t;
Cover(tr+s,tc,tr+s,tc+s-1,s);
if(max1>max2) return max1;
else return max2;
}
例:在n个元素中找最大值和最小值
template<class T>
void MaxMin(T a[], int l, int r, T &max, T &min)
{
if(l==r)
{ max = min = a[l]; return; }
int **Board;
void Cover(int tr,int tc,int dr,int dc,int size) //棋盘覆盖函数
{
if(size==1) return; //如果棋盘规模=1,返回
int s=size/2; //分割棋盘
int t=++tile; //L型骨牌编号加1
//处理左上角子棋盘
{ // 将a[s..t]进行2-路归并排序,利用b数组。
if (s==t) return;
int m = (s+t)/2; // 将a[s..t]平分为a[s..m]和a[m+1..t]
Msort(a, b, s, m);
Msort(a, b, m+1, t);
Merge(a, b, s, m, t); // 将a[s..m]和a[m+1..t]归并到b[s..t]