(待补全)
2.3-2
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void merge(int A[], int p, int q, int r)//归并排序
{
int i,j,k;
int n1,n2;
n1 = q - p + 1;
n2 = r - q;
int *L = new int[n1];
int *R = new int[n2];
for(i = 0; i < n1; i++)
L[i] = A[p + i];
//测试代码
for(i = 0; i < n1; i++)
cout<<L[i]<<" ";
cout<<endl;//
for(j = 0; j < n2; j++)
R[j] = A[q + 1 + j];
//测试代码
for(j = 0; j < n2; j++)
cout<<R[j]<<" ";
cout<<endl;//
i = j = 0;
for(k = p; k <= r; k++)
{
if( i != n1 && j != n2 && L[i] <= R[j])
{
A[k] = L[i];
i++;
}
else if(i != n1 && j != n2 && L[i] > R[j])
{
A[k] = R[j];
j++;
}
else if(i == n1)
{
A[k] = R[j];
j++;
}
else if(j == n2)
{
A[k] = L[i];
i++;
}
}
delete[] L;
delete[] R;
}
void main()
{
int A[] = {3,26,41,52,9,38,49,57};
merge(A, 0, 3, 7);
for(int i = 0; i< 8; i++)
cout<<A[i]<<" ";
}
2.3-4
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void insert_sort(int A[], int length)
{
int i;
int key;
if(length > 1)
{
insert_sort(A, length - 1);
i = length - 2;
key = A[length - 1];
while(i >= 0 && key < A[i])
{
A[i + 1] = A[i];
i--;
}
A[i + 1] = key;
}
}
void main()
{
int A[] = {31, 41, 59, 26, 41, 58};
insert_sort(A, 6);
for(int i = 0; i < 6; i++)
cout<<A[i]<<" ";
}
2.3-5
// stdafx.cpp : 只包括标准包含文件的源文件
// jj.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
#include<iostream>
// TODO: 在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用
using namespace std;
void binary_search(int v, int A[], int lowbound, int uperbound)
{
int midkey = (lowbound + uperbound) / 2;
if((A[midkey] > v) && lowbound != midkey)
binary_search(v, A, lowbound, midkey);
else if(A[midkey] < v && uperbound != midkey+1)
binary_search(v, A, midkey + 1, uperbound);
else if (A[midkey] == v)
cout<<midkey;
else if(lowbound == midkey && A[midkey] == v) //一定要考虑边界情况
cout<<lowbound;
else if(uperbound == midkey + 1 && A[midkey + 1] == v)
cout<<uperbound;
else //lowbound = middlekey
cout<<"NIL";
}
void main()
{
int A[]={ 21, 23, 45, 78,90};
binary_search(45, A, 0, 4);
}
补:写完这段代码后,又参看了一下答案中的伪代码,觉得自己写的这段代码太没有美感了,那么多if,else,有好几个可以合并的。周末在家又新写了一个比较好一点的,并纠正了两个拼写错误的单词lower,upper:
void binary_search(int v, int A[], int lower, int upper)
{
if(lower < upper)
{
int midpoint = (lower + upper) / 2;
if(A[midpoint] > v)
binary_search(v, A, lower, midpoint - 1);
else if(A[midpoint] < v)
binary_search(v, A, midpoint + 1, upper);
else
cout<<midpoint;
}
else
{
if(A[lower] == v)
cout<< lower;
else
cout<<"NIL";
}
}
2.3-6使用二分法搜索插入位置的insert-sort
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int binary_search(int key, int A[], int lower, int upper) //输出应该插入的位置的下标,原数组中从这个下标起,到数组的最后一个元素都要依次向后移一位。
{
if(lower < upper && lower + 1 != upper) //数组中不止有两个元素
{
int midpoint = (lower + upper) / 2;
if(A[midpoint] > key)
binary_search(key, A, lower, midpoint - 1);
else if(A[midpoint] < key)
binary_search(key, A, midpoint + 1, upper);
else
return midpoint + 1;
}
else if(lower < upper && lower + 1 == upper) //数组中只有2个元素
{
if(A[lower] < key && key < upper)
return lower + 1;
else if(key <= A[lower])
return lower;
else
return upper + 1;
}
else //数组中只有1个元素
{
if(key <= A[lower])
return lower;
else
return lower + 1;
}
}
void insert_sort(int A[], int length)
{
int i;
if(length > 1)
{
insert_sort(A, length - 1);
int key = A[length - 1];
int insert_index = binary_search(key, A, 0,length - 2);
for(i = length - 1; i >= insert_index; i--)
A[i] = A[i - 1];
A[insert_index] = key;
}
}
void main()
{
int A[] = {31, 41, 59, 26, 41, 58, 4};
insert_sort(A, 7);
for(int i = 0; i < 7; i++)
cout<<A[i]<<" ";
}虽然使用了二分查找,但是运行时间是
虽然使用了二分查找,但是运行时间为NlgN吗?计算方法参看《introduction to algorithms 3rd》page83:4.3,4.4,4.5:如何计算递归耗时(solving recurrences)
2.3-7
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void merge(int A[], int p, int q, int r)
{
int length1 = q - p + 1;
int length2 = r - q;
int *L = new int[length1];
int *R = new int[length2];
int i,j;
for(i = 0; i < length1; i++)
L[i] = A[p + i];
for(i = 0; i < length2; i++)
R[i] = A[q + i + 1];
i = j = 0;
while(p <= r)
{
if(i < length1 && j <= length2)
{
if(L[i] < R[j])
A[p++] = L[i++];
else
A[p++] = R[j++];
}
else if(i == length1)
A[p++] = R[j++];
else
A[p++] = L[i++];
}
delete[] L;
delete[] R;
}
void merge_sort(int A[], int p, int r)
{
if(p < r)
{
int q = (p + r) / 2;
merge_sort(A, p, q);
merge_sort(A, q + 1, r);
merge(A, p, q, r);
}
}
bool search_between(int x, int A[], int n1, int lower, int upper)
{
bool exist = false;
if(lower == upper)
{
if(A[n1] + A[lower] == x)
exist = true;
}
else //lower < upper
{
if(A[n1] + A[lower] == x)
exist = true;
else if(A[n1] + A[upper] == x)
exist = true;
else
{
int midpoint = (lower + upper) / 2;
if(A[n1] + A[midpoint] < x)
search_between(x, A, n1, midpoint + 1, upper);
else if(A[n1] + A[midpoint] > x)
search_between(x, A, n1, lower, midpoint); //边界问题要处理好,如果midpoint == lower,midpoint - 1就超界了。
else
exist = true;
}
}
return exist;
}
void search(int x, int A[], int length)
{
int i;
bool exist = false;
for(i = 0; i < length - 2; i++)
{
exist = search_between(x, A, i, i + 1, length - 1);
if(exist)
{
cout<<"exist";
break;
}
}
if(!exist)
cout<<"doesn't exist";
}
void main()
{
int A[] = {31, 41, 59, 26, 41, 58, 9};
merge_sort(A, 0, 6);
search(45, A, 7);
}