考研數據結構之查找(9.8)——練習題之編寫一個函數利用二分查找算法在一個有序表中插入關鍵字k並保持表的有序性(C表示)

題目

編寫一個函數,利用二分查找算法在一個有序表中插入一個關鍵字k,並保持表的有序性。

分析

先在有序表中利用二分查找算法查找關鍵字值等於或小於k的結點,m指向正好等於k的結點或l指向關鍵字正好大於k的結點,然後採用移動法插入k結點即可。

本題的難點就是如何利用二分查找算法找到合適的插入位置。

有兩種情況:第一種是有序表中沒有等於關鍵字k的結點,尋找大於k的結點即可;第二種是有序表中存在等於關鍵字k的結點,尋找等於k的結點即可。

圖解如下:

將兩種情況用同一部分代碼來處理,定義一個標誌位變量flag,用來記錄是否有等於關鍵字k的情況,初始爲0表示沒有等於關鍵字k的情況,如果有則將flag置爲1,然後退出循環,最終根據標誌位flag來判斷插入位置。

代碼

核心代碼:

/* 使用二分查找在順序表中插入元素k */ 
void insertK(int nums[],int n,int k){
	int mid;// 記錄中間下標 
	int low=0,high=n-1;
	int flag=0;// 標誌,用來記錄是否有等於k的值 
	int pos;// 定義的變量,爲插入的位置 
	while(low<=high&&flag==0){// 循環當low>high時跳出循環 
		mid=(low+high)/2;
		if(nums[mid]==k){
			flag=1;// 如果發現有關鍵字等於k,則將標誌flag置爲1,退出循環然後插入k 
		}else if(nums[mid]>k){
			high=mid-1;
		}else if(nums[mid]<k){
			low=mid+1;
		}
	}
	/* 確定插入位置 */ 
	if(flag==1){// 如果flag爲1則發現序列中有關鍵字等於k,則使插入位置等於mid
		pos=mid; 
	}else{// 如果flag爲0則表示序列中沒有與關鍵字k相等的值,則插入位置爲low 
		pos=low;
	}
	/* 插入關鍵字k */
	for(int i=n-1;i>=pos;i--){
		nums[i+1]=nums[i];
	} 
	nums[pos]=k;
}

完整代碼如下:

#include<stdio.h>

/* 打印數組 */ 
void printArr(int nums[],int n){
	printf("\n");
	for(int i=0;i<n;i++){
		printf("%d\t",nums[i]);
	}
	printf("\n");
}

/* 使用二分查找在順序表中插入元素k */ 
void insertK(int nums[],int n,int k){
	int mid;// 記錄中間下標 
	int low=0,high=n-1;
	int flag=0;// 標誌,用來記錄是否有等於k的值 
	int pos;// 定義的變量,爲插入的位置 
	while(low<=high&&flag==0){// 循環當low>high時跳出循環 
		mid=(low+high)/2;
		if(nums[mid]==k){
			flag=1;// 如果發現有關鍵字等於k,則將標誌flag置爲1,退出循環然後插入k 
		}else if(nums[mid]>k){
			high=mid-1;
		}else if(nums[mid]<k){
			low=mid+1;
		}
	}
	/* 確定插入位置 */ 
	if(flag==1){// 如果flag爲1則發現序列中有關鍵字等於k,則使插入位置等於mid
		pos=mid; 
	}else{// 如果flag爲0則表示序列中沒有與關鍵字k相等的值,則插入位置爲low 
		pos=low;
	}
	/* 插入關鍵字k */
	for(int i=n-1;i>=pos;i--){
		nums[i+1]=nums[i];
	} 
	nums[pos]=k;
}

int main(){
	int nums[]={1,2,3,4,5,6,7};
	int n=7;
	int k=5;
	insertK(nums,n,k);// 插入k
	printArr(nums,n);// 打印數組 
	
	return 0;
}

運行結果:

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