2.3-系列習題總結

(待補全)

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);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章