【数据结构】顺序表

版权声明:无意呢。 https://blog.csdn.net/qq_41900081/article/details/86529880

顺序表示一种最为简单的线性结构,可以分为两种,一种是静态顺序表,一种是动态顺序表
1)静态顺序表

所谓静态顺序表是指一旦定义了该表,其大小始终固定不变,函数调用时,静态顺序表在函数栈上开辟空间,我们熟悉的数组就是一种静态顺序表

e.g

  #definde MAXSIZE 100
  ElemType Sqlist[MAXSIZE];
  int len;

2)动态顺序表

所谓动态顺序表是一种更为灵活的顺序表,它创建在内存的动态存储区,也就是创建在堆内存,因此其长度是可以变化的

e.g

#define MAXSIZE 10
#define INCREMENTSIZE 10
typedef struct{
	ElemType *elem;
	int length;
	int listsize;
	int incrementsize;
}Sqlist;
  1. 向顺序表中插入第i个位置插入元素
//向顺序表第i个位置插入元素 
int InsertElem(Sqlist *L,int i, int item){
	//向顺序表L第i个位置插入元素item 
	int *base, *intserPtr, *p;
	//非法插入 
	if(i < 1 || i > L->length+1){
		return 0;
	}	
	
	if(L->length >= L->listsize){
		//重新追加空间 
		base = (int*)realloc(L->elem,(L->incrementsize+L->listsize)*sizeof(int));
		if(base == NULL) return 0;
		//更新内存基地址 
		L->elem = base;
		L->listsize += L->incrementsize;
	}
	//插入的位置 
	intserPtr = &(L->elem[i-1]);
	//将i-1后的元素顺序后移一个元素的位置 
	for(p = &(L->elem[L->length-1]); p >= intserPtr; p--){
		*(p+1) = *p;
	}	
	
	*intserPtr = item;
	L->length++;
	return 1;
}
  1. 编程实现顺序表的逆置
//顺序表的逆置
void reverseSqlist(Sqlist *L){
	int buf;
	int low = 0;
	int high = L->length-1;
	
	while(low < high){
		buf = L->elem[low];
		L->elem[low] = L->elem[high];
		L->elem[high] = buf;	
		low++;
		high--;	
	}	
}
  1. 编程实现删除顺序表中的重复元素
//删除顺序表的重复元素 
void purge(Sqlist * L){
	int i,j;
	for(i = 0;i < L->length;i++){
		if(L->elem[i] != FLAG){
			for(j = i+1;j < L->length; j++){
				if(L->elem[j] == L->elem[i]){
					L->elem[j] = FLAG;
				}
			}
		}
	}

	for(i = 0;L->elem[i] != FLAG; i++);
	for(j = i+1;j < L->length;){
		if(L->elem[j] != FLAG){
			L->elem[i++] = L->elem[j++];
		
		}else{
			j++;
		}
	}
	L->length = i;
} 
  1. 顺序表元素两两绝对值的最小值

有一个整数数组,求出两两绝对值的最小值,要求:只要求出最小值即可,不需要求出是哪两个数

//顺序表元素两两之差绝对值的最小值
int getMinDifference(Sqlist *L){
	int Min = 100;
	for(int rank = 0;rank < L->length; rank++)
		for(int row = rank +1;row < L->length;row++){
		    int buf = abs(L->elem[row] - L->elem[rank]);
			if( buf < Min){
				Min = buf; 
			}  
		}
	return Min;
} 
  1. 重新排列使得顺序表左边为奇数,右边为偶数

要求:空间复杂度为O(1),时间复杂度为O(n)

//重新排列使得顺序表左边为奇数,右边为偶数
int reArrange(Sqlist *L){
	int low = 0,high = L->length;

	while(true){
		while(L->elem[low] % 2 != 0 ) {
		low++;			
		}
		while(L->elem[high] % 2 == 0) {
			high--;			
		}
		if(low < high){
			int temp = L->elem[low];
			L->elem[low] = L->elem[high];
			L->elem[high] = temp;
			low++;
			high--;
		}else{
			return 1;
		}

	}
	return 1;
} 
  1. 重新排列使得顺序表左边为奇数,右边为偶数且不改变原数据在顺序表中的先后顺序
int ReArrange(Sqlist *L){
	int i,j;
	//找到第一个偶数 
	for( i = 0;i < L->length;i++) {
		if(L->elem[i] % 2 == 0) break;
	} 
	for(int j = i + 1;j < L->length; j++){
		if(L->elem[j] % 2 != 0){
			int temp = L->elem[j];
			for(int k = j;k > i;k--){
				L->elem[k] = L->elem[k-1]; 
			}
			L->elem[i] = temp;
			i++;
		}
	}
	return 1;
} 

C/C++完整代码

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
using namespace std;
#define MAXSIZE 10
#define INCREMENTSIZE 10
#define FLAG -1
typedef struct{
	int *elem;
	int length;
	int listsize;
	int incrementsize;
}Sqlist;
//创建空顺序表 
int Init(Sqlist *L){
	
	L->listsize = MAXSIZE;
	L->incrementsize = INCREMENTSIZE;
	L->elem = (int *)malloc(sizeof(int)*L->listsize);	
	L->length = 0;
	
}
//打印顺序表 
int Print(Sqlist *L){
	if(L->length == 0){
        printf("NULL\n");
    }
    
    for(int i = 0; i < L->length; i++){
        printf("%d  ", L->elem[i]);
    }
     printf("\n\n");

}
//向顺序表第i个位置插入元素 
int InsertElem(Sqlist *L,int i, int item){
	//向顺序表L第i个位置插入元素item 
	int *base, *intserPtr, *p;
	//非法插入 
	if(i < 1 || i > L->length+1){
		return 0;
	}	
	
	if(L->length >= L->listsize){
		//重新追加空间 
		base = (int*)realloc(L->elem,(L->incrementsize+L->listsize)*sizeof(int));
		if(base == NULL) return 0;
		//更新内存基地址 
		L->elem = base;
		L->listsize += L->incrementsize;
	}
	//插入的位置 
	intserPtr = &(L->elem[i-1]);
	//将i-1后的元素顺序后移一个元素的位置 
	for(p = &(L->elem[L->length-1]); p >= intserPtr; p--){
		*(p+1) = *p;
	}	
	
	*intserPtr = item;
	L->length++;
	return 1;
}
//顺序表的逆置
void reverseSqlist(Sqlist *L){
	int buf;
	int low = 0;
	int high = L->length-1;
	
	while(low < high){
		buf = L->elem[low];
		L->elem[low] = L->elem[high];
		L->elem[high] = buf;	
		low++;
		high--;	
	}	
}
//顺序表的删除操作
int DelElem(Sqlist *L,int index){
	if(index < 0 || index > L->length) return 0;
	for(int i = 0;i < L->length-1; i++){
		if(i == index){
			L->elem[i] = L->elem[i+1]; 
		}
	}
	L->length--;
	return 1;
} 
//删除顺序表的重复元素 
void purge(Sqlist * L){
	int i,j;
	for(i = 0;i < L->length;i++){
		if(L->elem[i] != FLAG){
			for(j = i+1;j < L->length; j++){
				if(L->elem[j] == L->elem[i]){
					L->elem[j] = FLAG;
				}
			}
		}
	}

	for(i = 0;L->elem[i] != FLAG; i++);
	for(j = i+1;j < L->length;){
		if(L->elem[j] != FLAG){
			L->elem[i++] = L->elem[j++];
		
		}else{
			j++;
		}
	}
	L->length = i;
} 
//顺序表元素两两之差绝对值的最小值
int getMinDifference(Sqlist *L){
	int Min = 100;
	for(int rank = 0;rank < L->length; rank++)
		for(int row = rank +1;row < L->length;row++){
		    int buf = abs(L->elem[row] - L->elem[rank]);
			if( buf < Min){
				Min = buf; 
			}  
		}
	return Min;
} 
//重新排列使得顺序表左边为奇数,右边为偶数
int reArrange(Sqlist *L){
	int low = 0,high = L->length;

	while(true){
		while(L->elem[low] % 2 != 0 ) {
		low++;			
		}
		while(L->elem[high] % 2 == 0) {
			high--;			
		}
		if(low < high){
			int temp = L->elem[low];
			L->elem[low] = L->elem[high];
			L->elem[high] = temp;
			low++;
			high--;
		}else{
			return 1;
		}

	}
	return 1;
} 
//重新排列使得顺序表左边为奇数,右边为偶数且不改变数据在顺序表中的先后顺序
int ReArrange(Sqlist *L){
	int i,j;
	//找到第一个偶数 
	for( i = 0;i < L->length;i++) {
		if(L->elem[i] % 2 == 0) break;
	} 
	for(int j = i + 1;j < L->length; j++){
		if(L->elem[j] % 2 != 0){
			int temp = L->elem[j];
			for(int k = j;k > i;k--){
				L->elem[k] = L->elem[k-1]; 
			}
			L->elem[i] = temp;
			i++;
		}
	}
	return 1;
} 

//Test
int main() {
	Sqlist *L = new Sqlist;	
	Sqlist *Q = new Sqlist;
	//创建顺序表 
	Init(L); 
	Init(Q); 
	//初始化顺序表 
	for(int i = 1; i <= 15; i++){
		if(i % 2 == 0) {
		 InsertElem(L,i,i);
		}else{
			InsertElem(L,i,5);
		}
	}
	
	for(int i = 1; i <= 10; i++){	
		 InsertElem(Q,i,i);	
	}
	
	//打印顺序表 
	printf("顺序表:\n");
	Print(L);
	
	//顺序表的逆置
	reverseSqlist(L); 
	
	//打印逆置后的顺序表
	printf("逆置后的顺序表:\n");  
	Print(L);
	
	//删除重复元素
	purge(L);
	//打印删除重复元素后的顺序表
	printf("删除重复元素后的顺序表:\n");  
	Print(L);
	
	printf("顺序表元素两两之差绝对值的最小值:"); 
	cout<<getMinDifference(L)<<endl<<endl;
	
	//重新排列使得顺序表左边为奇数,右边为偶数
	/*reArrange(Q);
	printf("重新排列使得顺序表左边为奇数,右边为偶数:\n");  
	Print(Q);*/
	//重新排列使得顺序表左边为奇数,右边为偶数且不改变数据在顺序表中的先后顺序
	printf("重新排列使得顺序表左边为奇数,右边为偶数且不改变数据在顺序表中的先后顺序:\n"); 
	Print(Q);
	ReArrange(Q); 
	Print(Q);
	cout<<"动态顺序表的长度:"<<L->length<<endl;
	cout<<"动态顺序表所占的空间大小:"<<L->listsize<<endl; 
	delete L;
	delete Q; 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41900081/article/details/86529880