数据结构算法题(C++)

0 准备工作

在线C++运行工具

使用方法:复制每题中代码到上面的在线运行网站上便可以运行

第1章:线性表的顺序表示

01

题目:假设顺序表非空。从顺序表中找到最小值,及其下标,通过引用方式返回

思路:

①申请变量value,pos初始化value为顺序表第一个元素的值,pos=0

②从顺序表第二位开始遍历,遇见比value更小的元素,就更新value为当前元素,pos为当前元素的下标

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 

using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

// 假设顺序表非空,从顺序表中找到最小的只,及其下标,通过引用的方式返回 
void findMin(SqList &L, ElemType &value, int &pos) {
//	表中第一个元素的值 
	value = L.data[0];
	pos = 0;
//	从第二个位置开始 
	for(int i = 1; i < L.length; i++) {
//		遇到更小的更新 
		if(L.data[i] < value) {
			value = L.data[i];
			pos = i;
		}
	}
//	退出之后
//	pos:是最小元素在数组中的下标
//	value:是最小元素的值 
}
//测试findMin函数 
void test_findMin() {
	SqList L = getRandomSqList(10);     
	printList(L);   
	cout << "--------------------------------" << endl;   
	ElemType value;
	int pos;
	findMin(L, value, pos);
	cout << "最小值:" << value << ",下标:" << pos << endl; 
}

int main() {
	test_findMin();
	return 0;
}

02

题目:从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若顺序表为空则显示出错误信息并退出

思想:

①表空时:返回

②表非空

一:找到最小元素

二:然后用表尾元素覆盖,表长减去1

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

// 假设顺序表非空,从顺序表中找到最小的只,及其下标,通过引用的方式返回 
void findMin(SqList &L, ElemType &value, int &pos) {
//	表中第一个元素的值 
	value = L.data[0];
	pos = 0;
//	从第二个位置开始 
	for(int i = 1; i < L.length; i++) {
//		遇到更小的更新 
		if(L.data[i] < value) {
			value = L.data[i];
			pos = i;
		}
	}
//	退出之后
//	pos:是最小元素在数组中的下标
//	value:是最小元素的值 
}

//删除顺序表中最小值的元素,并有函数返回最小值,空出的位置由最后一个元素补充
bool delMin(SqList &L, ElemType &value) {
//	空表判断 
	if(L.length == 0) {
		return false;
	}
//	找到最小元素,最小元素下标 
	int pos;
	findMin(L, value, pos);
//	最后一位 
	int end = L.length - 1;
//	执行覆盖 
	L.data[pos] = L.data[end];
//	表长减一 
	L.length--;
	return true;
} 
//测试findMin函数 
void test_delMin() {
	SqList L = getRandomSqList(10);     
	printList(L);   
	cout << "--------------------------------" << endl;   
	ElemType value;
	int value1;
	delMin(L, value1);
	cout << "最小值:" << value1 << endl; 
	cout << "--------------------------------" << endl; 
	printList(L);   
}

int main() {
	test_delMin();
	return 0;
}

03

题目:交换ab元素值

思想:

申请变量C,先让c = a, 再让a = b,再让b = c,交换完成

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

//交换ab的值 
void swap(ElemType &a, ElemType &b) {
	ElemType c = a;
	a = b;
	b = c;
}

void test_swap() {
	ElemType a = 10, b = 20;
	cout << "a = " << a << ", b = " << b << endl;
	swap(a, b);
	cout << "a = " << a << ", b = " << b << endl;
}

int main() {
	test_swap(); 
	return 0;
}

04

题目:设计一个高效的算法,将顺序表L的所有元素逆置,要求算法的空间复杂度O(1)

思想:双指针,交换n/2次

①表长为偶数,头尾交换

②表长为奇数,中间的数不用交换

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

//交换ab的值 
void swap(ElemType &a, ElemType &b) {
	ElemType c = a;
	a = b;
	b = c;
}

//将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)
void reverse(SqList &L) {
	for(int i = 0; i < L.length/2; i++) {
//		末尾元素下标 
		int end = L.length - i - 1;
//		交换 
		swap(L.data[i], L.data[end]);
	}
} 

void test_reverse() {
	SqList L = getRandomSqList(11);
	cout << "表L:";
	printList(L);
	cout << "--------------------------------" << endl; 
	reverse(L);
	cout << "逆L:";
	printList(L);	 
}

int main() {
	test_reverse();
	return 0;
}

05

题目:用顺序表,实现简单选择排序

思想:

①第i趟:每一趟都可以确定一个元素的最终位置,从L[i...n]中选择关键字最小的元素与L[i]交换

②经过n-1唐排序就可以是的整个排序表有序

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

//交换ab的值 
void swap(ElemType &a, ElemType &b) {
	ElemType c = a;
	a = b;
	b = c;
}

//用顺序表实现简单选择排序
//找到下标start...end中的最小值下标,并返回
int findMinIndex(SqList A, int start, int end) {
	int minIndex = start;
	for(int j = start+1; j <= end; j++) {
		if(A.data[minIndex] > A.data[j]) {
			minIndex = j;
		}
	}
	return minIndex;
} 
//进行选择排序
//表分为两部分,前面有序,后面无序
//在i~end之间找到最小的元素,若是最小的元素的值与i不相等,则将i与最小元素的调换
//i从0~length-1 
//A必须进行引用,否则数组,length将会被复制一份 
void selectSort(SqList &A) {
	for(int i = 0; i < A.length; i++) {
//		第i趟,找出无序部分最小值下标 
		int minIndex = findMinIndex(A, i, A.length-1);
//		将无序部分最小值放到有序部分尾巴 
		if(minIndex != i) {
			swap(A.data[i], A.data[minIndex]);
		}
	}
}

void test_selectSort() {
	SqList L = getRandomSqList(10);
	cout << "表L:";
	printList(L);
	cout << "--------------------------------" << endl; 
	selectSort(L);
	cout << "序L:";
	printList(L);
}

int main() {
	test_selectSort(); 
	return 0;
}

06

题目:对长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素

思路:遍历整个表,记录所有当前不等于x的元素的个数,假设为k。将不等于x的元素放在下标为k上,最后修改表长为k

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

//对长度为n的顺序表L,时间复杂度O(n),空间复杂度O(1),删除L中所有x的数据元素
//将表L分为三个部分,第一部分为不是20的元素,第二部分为20, 第三部分为待排序的元素
//因为第二部分是在逻辑上的,实际操作上是被覆盖的 
void delX(SqList &L, ElemType x) {
//	记录表中值不等于x的元素的个数
//	最终也是表长 
	int k = 0;
//	遍历,执行处理 
	for(int i = 0; i < L.length; i++) {
		if(L.data[i] != x) {
//			把当前元素放在下标k处 
			L.data[k] = L.data[i];
//			k递增 
			k += 1;
		}
//		else:等于x的元素直接略过 
	}
//	表长最终等于k 
	L.length = k;
} 

void test_delX() {
	SqList L = getRandomSqList(10);
//	随机将L中的三个元素设置为20
	for(int i = 0; i < 3; i++) {
		L.data[rand() % 10] = 20;
	} 
	cout << "表L:";
	printList(L);
	cout << "--------------------------------" << endl; 
	delX(L, 20);
	cout << "表L:";
	printList(L);	
}

int main() {
	test_delX();
	return 0;
}

07

题目:从顺序表中删除位序位于i,j之间的所有元素

思路:如果i,j不合法,返回false,否则,把位序j之后的元素,依次移动到从位序i开始的位置上,最后修改表长为L.length-(j-i+1),返回true

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

//从顺序表L中删除位序i和j之间的元素
//位序是从1~length 
//将L分为三段,其中0~i-2是第一段,i-1~j-1是第二段,j~length-1是第三段
//第一段是加1的,第三段是减1的,第二段不需要管
bool deli2j(SqList &L, int i, int j) {
//	首先先对i和j和合法性进行判断
	if(i < 1 || j > L.length || j < i) {
		return false;
	} 
//	位序转换为下标 
	i--;
	j--;
//	将indexJ出元素移动到indexI处
//	到表尾时停止
//	移动一个元素后就后退一位 
	for(int indexI = i, indexJ = j+1; indexJ < L.length; indexI++, indexJ++) {
//		移动 
		L.data[indexI] = L.data[indexJ];
	} 
//	修改表长
	L.length -= j - i + 1;
	return true; 
} 

void test_deli2j() {
	SqList L = getRandomSqList(16);
	
	cout << "注意位序和下标有1的差距" << endl;
	cout << "表L:";
	printList(L);
	cout << "----------------------------------------------------------------" << endl; 
	cout << "原来表长:" << L.length << endl;
	deli2j(L, 4, 8);
	cout << "现在表长:" << L.length << endl;
	cout << "表L:";
	printList(L);
}


int main() {
	test_deli2j();
	return 0;
}

08

题目:找出有序表中值在给定值s和t之间的所有元素,返回下标范围

思想:确定值在[s,t]之间的元素的下标

①从头到尾遍历,第一个出现的元素值大于等于s的元素

②从头到尾遍历,第一个出现的元素值大于t的元素的前一个元素

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

//交换ab的值 
void swap(ElemType &a, ElemType &b) {
	ElemType c = a;
	a = b;
	b = c;
}

void bubbSort(SqList &L) {
	int n = L.length;
	for(int i = 0; i < n - 1; i++) {
//		用于标记本轮冒泡排序是否进行了交换 
		bool isBubble = false;
//		从后往前冒泡 
		for(int j = n - 1; j > i; j--) {
//			前面的更大,则需要交换 
			if(L.data[j - 1] > L.data[j]) {
				swap(L.data[j - 1], L.data[j]);
				isBubble = true;
			}
		}
//		如果没有交换则证明已经有序了
		if(!isBubble) {
			return;
		} 
	}
}

//找到有序顺序表中值在给定s与t之间(要求s<t)的所有元素,返回下标范围
//从头到尾遍历,第一个出现s和t的下标位置 
bool finds2t(SqList &L, ElemType s, ElemType t, int &start, int &end) {
//	合法性判断
	if(s >= t || L.length == 0) {
		return false;
	} 
	
	int indexS;
	for(indexS = 0; indexS < L.length && L.data[indexS] < s; indexS++);
	if(indexS >= L.length) {
		return false;
	}
	int indexT;
	for(indexT = indexS; indexT < L.length && L.data[indexT] <= t; indexT++);
	start = indexS;
	end = indexT - 1;
	return true;
}

void test_finds2t() {
	SqList L = getRandomSqList(10);
	bubbSort(L);
	cout << "表L:";
	printList(L);
	cout << "--------------------------------" << endl; 
	ElemType s = 10, t = 40;
	int start, end;
	cout << "寻找[" << s << ", " << t << "]之间的元素: ";
	bool isSuccess =  finds2t(L, s, t, start, end);
	cout << "[" << start << ", " << end << "]" << endl;	
}

int main() {
	test_finds2t();
	return 0;
}

09

题目:从有序顺序表中删除其值在给定值s与t之间的所有元素,如果s或t不合理或顺序表为空,则显示出错信息并退出运行

思想:

①有序顺序表:表中元素我们假设是递增的

②确定值在[s,t]之间的元素的下标

③执行区间删除

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

void bubbSort(SqList &L) {
	int n = L.length;
	for(int i = 0; i < n - 1; i++) {
//		用于标记本轮冒泡排序是否进行了交换 
		bool isBubble = false;
//		从后往前冒泡 
		for(int j = n - 1; j > i; j--) {
//			前面的更大,则需要交换 
			if(L.data[j - 1] > L.data[j]) {
				swap(L.data[j - 1], L.data[j]);
				isBubble = true;
			}
		}
//		如果没有交换则证明已经有序了
		if(!isBubble) {
			return;
		} 
	}
}

//找到有序顺序表中值在给定s与t之间(要求s<t)的所有元素,返回下标范围
//从头到尾遍历,第一个出现s和t的下标位置 
bool finds2t(SqList &L, ElemType s, ElemType t, int &start, int &end) {
//	合法性判断
	if(s >= t || L.length == 0) {
		return false;
	} 
	
	int indexS;
	for(indexS = 0; indexS < L.length && L.data[indexS] < s; indexS++);
	if(indexS >= L.length) {
		return false;
	}
	int indexT;
	for(indexT = indexS; indexT < L.length && L.data[indexT] <= t; indexT++);
	start = indexS;
	end = indexT - 1;
	return true;
}

//从顺序表L中删除位序i和j之间的元素
//位序是从1~length 
//将L分为三段,其中0~i-2是第一段,i-1~j-1是第二段,j~length-1是第三段
//第一段是加1的,第三段是减1的,第二段不需要管
bool deli2j(SqList &L, int i, int j) {
//	首先先对i和j和合法性进行判断
	if(i < 1 || j > L.length || j < i) {
		return false;
	} 
//	位序转换为下标 
	i--;
	j--;
//	将indexJ出元素移动到indexI处
//	到表尾时停止
//	移动一个元素后就后退一位 
	for(int indexI = i, indexJ = j+1; indexJ < L.length; indexI++, indexJ++) {
//		移动 
		L.data[indexI] = L.data[indexJ];
	} 
//	修改表长
	L.length -= j - i + 1;
	return true; 
} 

//从有序顺序表中删除值在s到t之间的所有元素,如果s和t不合理或顺序表为空,则显示出错信息并退出运行
bool dels2t(SqList &L, ElemType s, ElemType t) {
	int start, end;
	bool isSuccess;
	isSuccess = finds2t(L, s, t, start, end);
	if(!isSuccess) {
		return false;
	}
	return deli2j(L, start+1, end+1);
} 

void test_dels2t() {
	SqList L = getRandomSqList(10);
	bubbSort(L);
	cout << "表L:";
	printList(L);
	cout << "--------------------------------" << endl; 
	
	ElemType s = L.data[4], t = L.data[7];
	cout << "删除[" << L.data[4] << "," << L.data[7] << "]之间的元素" << endl;
	dels2t(L, s, t);
	cout << "删L:";
	printList(L);
}

int main() {
	test_dels2t(); 
	return 0;
}

10

题目:从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同

思路:

①将表划分为A表,B表;A表是该有序顺序表的前半部分,B表是该表的后半部分

②初始化是,表A中只有一个元素,也就是有序顺序表的第一个元素,表B拥有剩下的n-1个元素

③用表A的最后一个元素与表B从头开始比较没出现不相同时,追加到表A尾巴上

④重复③,知道表B为空,再修改新表长为表A的长度

#define MaxSize 50
#include <iostream>
#include <stdlib.h>
#include <time.h> 
using namespace std;
typedef int ElemType;
typedef struct {
	ElemType data[MaxSize];
	int length;
}SqList;

//打印出数组元素,以逗号隔开 
void printList(SqList L) {
	for(int i = 0; i < L.length; i++) {
		cout << L.data[i] << ", ";
	}
	cout << endl;
}
// number表示数组中的元素个数,L表示保存在L链表中
// 数组的范围是1~100 
SqList getRandomSqList(int number) {
	SqList L;
	L.length = number;
	srand((unsigned)time(NULL)); 
	for(int i = 0; i < number;i++ ) {
		int val = rand() % 100;
		L.data[i] = val;
//		cout << number << "\t";
	}
//    cout << endl; 
	return L;
}

bool delSame(SqList &L) {
//	表空不存在删除 
	if(L.length == 0) {
		return false;
	}
//	在表A,B 中进行索引的指针 
	int indexA, indexB;
	for(indexA = 0, indexB = 1; indexB < L.length; indexB++) {
//		出现不同的元素,应该放到表A的尾巴上去 
		if(L.data[indexA] != L.data[indexB]) {
			L.data[++indexA] = L.data[indexB];
		}
	}
//	最终表长为表A的长度 
	L.length = indexA + 1;
//	对于是否加1.一定要弄清楚当前indexA是只想表A的最后一个元素(加1)
//	还是指向表A的最后一个元素的下一个元素(不加1) 
	return true;
}

void test_delSame() {
	SqList L;
	ElemType A[] = {1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5};
	L.length = sizeof(A) / sizeof(ElemType);
	for(int i = 0; i < L.length; i++) {
		L.data[i] = A[i];
	} 
	cout << "表L:";
	printList(L);
	cout << "--------------------------------" << endl; 
	delSame(L);
	printList(L);
} 

int main() {
	test_delSame();
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值