順序表中的最小正整數問題

一 概述

在保存整數的順序表L中查找未出現的最小正整數,如,順序表[-5 3 2 3]中未出現的最小正整數爲1,順序表[1 2 3 4]中未出現的最小正整數爲5。

二 算法思想

題外話:在早些時候,存儲技術沒有這麼發達,所以在計算機某些實現方面採用的是時間換空間,隨着存儲技術的發展,現在時間對於很多領域來說,比空間更加重要,所以,現在大多情況下是採用空間換時間的方法。

我們分配一個用於標記的數組Sign[L.length],用以記錄L中是否出現了1~L.length中的正整數,Sign[0]對應正整數1,而Sign[n-1]對應正整數L.length,初始化時Sign中的值全爲0。由於L中包含L.length個整數,因此可能返回的值是1~L.length+1,當A中n個數恰好爲1~L.length是,直接返回未出現的最小正整數是L.length+1。當線性表L中出現了小於等於0或者大於L.length的值是,就會導致1~L.length中出現空餘位置。則未出現的最小正整數必然在1~L.length中,因此對於L中出現了小於等於0或大於L.length的值可以不採取任何操作。

算法流程:從L.elem[0]開始遍歷順序表L,若0<L[i]<=L.length,則令Sign[L[i]-1] =3,其實可以定義爲一個任何不爲零的數以區別Sign[i]中初始化爲0的情況,否則不做任何操作;對於遍歷完L之後,開始遍歷標記數組Sign[],若能夠查找到第一個滿足Sign[i]==0的下標i,返回i+1,即爲未出現的最小正整數,此時說明L中未出現的最小正整數在1~L.length之間。若Sign[i]中的數據全部不爲0,返回i+1,此時的i=L.length,i+1即爲L.length+1,說明L中未出現的最小正整數是n+1。

三 算法實現

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int Status;
typedef int ElemType;

#define MAXSIZE 100
#define ERROR -1
#define OK 0

typedef struct {
	ElemType *elem;
	int length;
}SqList; 

Status init_Queue(SqList &L){
	
	L.elem = new ElemType[MAXSIZE]; //初始化最大長度的順序表 
	
	if(!L.elem){
		return ERROR; //初始化失敗 
	}
	
	L.length = 0; //初始時數據表爲空 
	return OK;
}

int findMissMinInt(SqList &L) {
	int i, *Sign; //標記數組*Sign是一個指針類型,此處Sign中是數組的地址
	
	/*如:*a = b;
	此時:a中保存的是變量b的內存地址;
		 *a則是取變量b的值。 
		 &b就是取變量b的地址。 
	*/  
	
	Sign = (int *)malloc(sizeof(int)*L.length); //C語言分配數組空間 
	//memset(Sign,0,sizeof(int)*L.length);
	memset(Sign,0,sizeof(Sign)); //將標記數組元素全部賦值爲0 
	
	for(i = 0; i < L.length;i++) {
		if(L.elem[i] > 0 && L.elem[i] <= L.length){
			Sign[L.elem[i] - 1] = 3; 
		}
	}
	
	for(i = 0; i < L.length;i++) {
		if(Sign[i] == 0) {
			break;
		} 
	}
	return i+1;
}

int main(){
	SqList L;
	printf("1.初始化順序表!\n");
	printf("2.輸入8個不同的數字!\n");
	printf("3.順序表L中未出現的最小正整數!\n");
	printf("0.退出!\n");
	
	int elect = -1,length;
	
	while(elect !=0){
		printf("請選擇你的後續操作:"); 
		scanf("%d",&elect);
		switch(elect){
			case 1:
				if(!init_Queue(L)){
					printf("初始化順序表成功!\n"); 
				}else{
					printf("初始化順序表失敗!\n"); 
				}
				break;
			case 2:
				printf("請初始化順序表的長度:");
				scanf("%d",&length); 
				printf("請輸入%d個整數:",length);
				for(int i = 0; i < length; i++){
					scanf("%d",&L.elem[i]);
					L.length = length; 
				}
				break;
			case 3:
					printf("順序表L中未出現的最小正整數爲:%d\n",findMissMinInt(L)); 
				break;
		}
	}
	return OK;
}

算法結果,當Sing[]中存在0值:

算法結果,當Sign[]中不存在0值:

四 算法的時間複雜度和空間複雜度分析

算法時間複雜度:按順序查找的時間複雜度分析,該算法的時間複雜度爲O(n)。

算法空間複雜度:在算法實現過程中,使用標記數組Sign[n]作爲輔助空間,故該算法的空間複雜度爲O(n)。

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