(待補全)
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);
}