题目十:分治法的应用
1.设计内容:
利用分治法实现多种问题,并分析、编程和总结,给出结论。
2.设计要求:
(1)给出分治法思想;
(2)给出数据查找的算法和程序;
(3)给出合并排序算法和程序;
(4)给出快速排序算法和程序;
(5)给出分治法的时间复杂度。
数据查找
程序:
#include<bits/stdc++.h>
#define MAX 911
using namespace std;
void QS(int *a, int l, int r);
bool QF(int *a, int l, int r, int key);
int main()
{
int n, a[MAX],key;
cout<<"输入数组长度:";
cin>>n;
cout<<"输入数组元素:";
for(int i = 0; i < n; i++)
cin>>a[i];
cout<<"输入要查找元素:";
cin>>key;
QS(a,0,n-1);
if(QF(a,0,n-1,key))
cout<<"找到。"<<endl;
else
cout<<"数组中无该元素!"<<endl;
}
void QS(int *a, int l, int r)
{
if(l >= r)
return;
int i = l, j = r, temp = a[l];
while(i < j)
{
while(a[j] >= temp && j > i)
j--;
a[i] = a[j];
while(a[i] <= temp && i < j)
i++;
a[j] = a[i];
}
a[j] = temp;
QS(a, l, j - 1);
QS(a, j + 1, r);
}
bool QF(int *a, int l, int r, int key)
{
if(l > r)
return 0;
int mid = (l + r)/2;
if(key == a[mid])
return 1;
else if(key > a[mid])
return QF(a, mid+1, r, key);
else
return QF(a, l, mid-1, key);
}
合并排序程序:
#include<iostream>
using namespace std;
void MergeSort(int *s, int l, int r); ///r是下标而不是长度
void Merge(int *s, int *s1, int l, int mid, int r);
void Copy(int *s, int *s1, int l, int r);
int main()
{
int n;
cout<<"输入序列的长度n:"<<endl;
cin>>n;
int *s = new int[n];
cout<<"输入序列的元素:"<<endl;
for(int i = 0; i < n; i++)
cin>>s[i];
MergeSort(s, 0, n-1);
for(int i = 0; i < n - 1; i++)
cout<<s[i]<<" ";
cout<<s[n-1]<<endl;
}
void MergeSort(int *s, int l, int r)
{
if(l < r)
{
int mid = (l + r) / 2;
MergeSort(s, l, mid);
MergeSort(s, mid + 1, r);
int s1[r-l+1];
Merge(s, s1, l, mid, r);
Copy(s, s1, l, r);
}
}
void Merge(int *s, int *s1, int l, int mid, int r)
{
int i = l, j = mid + 1, k = 0;
while(i <= mid && j <= r)
{
while(i <= mid && s[i] > s[j])
s1[k++] = s[i++];
while(j <= r && s[i] <= s[j])
s1[k++] = s[j++];
}
while(i <= mid) s1[k++] = s[i++];
while(j <= r) s1[k++] = s[j++];
}
void Copy(int *s, int *s1, int l, int r)
{
int i, j = 0;
for(i = l; i <= r; i++)
s[i] = s1[j++];
}
快速排序
基本思想:
快排就是给一数组,选择数组中的一个元素key,通常是第一个或最后一个。升序时把所有大于Key的元素都移到Key的右边,小于Key的都移到Key左边,这是一次快排,然后再对元素Key左右两端的元素进行快排。
基本思想:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序程序:
#include<bits/stdc++.h>
using namespace std;
void QSort(int *a, int l, int r);
int main()
{
int n;
cout<<"输入序列长度n = ";
cin>>n;
int *a = new int[n];
cout<<"输入序列的元素:"<<endl;
for(int i = 0; i < n; i++)
cin>>a[i];
QSort(a,0,n-1);
cout<<"快排后的结果:"<<endl;
for(int i = 0; i < n - 1; i++)
cout<<a[i]<<" ";
cout<<a[n-1]<<endl;
}
void QSort(int *a, int l, int r)
{
if(l > r)
return ;
int i = l, j = r, key = a[l];
while(i < j)
{
while(a[j] >= key && j > i)
j--;
a[i] = a[j];
while(a[i] <= key && i < j)
i++;
a[j] = a[i];
}
a[i] = key;
QSort(a, l, j - 1);
QSort(a, j + 1, r);
}