考研王道数据结构课后题(代码应用题)

线性表习题

  • 王道课后题
    • 顺序表
      • 1.从顺序表中删除具有最小值的元素
      • 2.将顺序表L所有元素逆置
      • 3.删除顺序表中所有值为x的元素
      • 4.从有序表中删除元素值在s与t之间的所有元素
      • 5.从顺序表中删除元素值在s与t之间的所有元素
      • 6.从有序表中删除所有值重复的元素
      • 7.★将两个有序顺序表合并成一个新的有序顺序表
      • 8.(难)一个数组A[m+n]中有两个顺序表,将两个顺序表位置互换
      • 9.顺序表元素递增有序,用最少时间查找数值为x的元素
      • 10.将R中序列循环左移p个位置
    • 链表
      • 1.删除不带头结点的单链表L中所有值为x的节点
      • 2.单链表L(带头结点),删除所有值为x的节点,并释放其空间
      • 3.单链表(带头节点)从尾到头反向输出每个节点
      • 4.在单链表(带头结点)中删除一个最小值节点
      • 5.将带头结点的单链表就地逆置(空间复杂度为O(1))
      • 6.带头结点的单链表,使其元素递增有序
      • 7.带头结点单链表无序,删除所有介于两个给定值s和t之间的元素
      • 8.两个单链表,找到公共节点
      • 9.按递增次序输出单链表中各节点的数据元素,并释放节点空间
      • 10.带头结点单链表A,将其中奇数位置元素放在A,偶数在B
      • 12.递增有序单链表,去掉数值相同元素
      • 21.查找链表中倒数第K各节点
    • 循环链表
      • 18.两个循环链表h1和h2,将h2合并到h1中
      • 19.带头结点循环单链表反复找到最小节点输出,并删除
      • 22.判断一个链表是否有环
      • 25.后半部分逆置插入前段部分
      • 1.判断输入输出序列是否为合法序列
      • 2.判断链表中n个字符是否中心对称
      • 3.两个栈共享空间
    • 栈和队列应用
      • 1.判断表达式中的括号是否匹配问题,‘\0’作为结束符

王道课后题

顺序表

1.从顺序表中删除具有最小值的元素

并由函数返回被删除元素,空出位置由最后一个元素填补,若顺序表为空,则显示错误信息并推出运行

//分析1.找到最小元素下标
//	  2.返回该元素
//	  3.将最后一个元素覆盖最小元素
//	  4.将length-1
bool DeleteMinElem(SqList &L,ElemType &e){
	if(L.length == 0)
		return false;
	int min = L.data[0];
	int pos;
	for(int i = 1;i < L.length;i++){
		if(min > L.data[i]){
			min = L.data[i];
			pos = i;	//跳出循环i就没了
		}
	}
	 L.data[pos] = L.data[L.length - 1];
	 length--;
	 return true;
}

2.将顺序表L所有元素逆置

要求算法的时间复杂度为O(1)

//分析:扫描前半部分元素,与后半部分元素互换,界限为L.length / 2
void Reverse(SqList &L){
	ElemType temp;
	for(int i = 0;i < L.length / 2;i++){
		temp = L.data[i];
		L.data[i] = L.data[L.length - 1 - i];//0~length-1,1~length-1-1,i~length-1-i
		L.data[L.length - 1 - i] = temp;
	}
}

3.删除顺序表中所有值为x的元素

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

//分析:将不为x的元素前移
bool DeleteX(SqList &L,ElemType e){
	int k = 0;	//有一个x元素就滞后i一次
	for(int i = 0;i < L.length;i++){
		if(L.data[i] != x){				
			L.data[k] = L.data[i];			//删除元素时常用思想:前移
			k++;							//不是要删除的元素就k++,是就不加,与i形成错位
		}
	}
	L.length = k;
}

4.从有序表中删除元素值在s与t之间的所有元素

要求s<t,若s或t不合理或顺序表为空时,显示错误

//分析:1.排除错误情况
//	   2.分别找到位置为s和t的元素
//	   3.将t的元素代替s的元素即删除
//	   4.修改长度
bool DeleteSToT(SqList &L,ElemType s,ElemType t){
	int num_s,num_t;
	if(s >= t || L.length == 0)			//排除错误情况
		return false;
	for(int i = 0;i < L.length;i++){	//找到s下标
		if(L.data[i] == s){
			num = i;
			break;
		}
	}
	if(i >= L.length)
		return false;
	for(int j = 0;j < L.length;j++){	//找到t下标
		if(L.data[j] == t){
			num = j;
			break;
		}
	}
	while(j < L.length){				//替换
		L.data[i] = L.data[j];
		i++;
		j++;
	}
	L.length = i;						//改长度
	return true;
}
//王道答案
bool DeleteSToT(SqList &L,ElemType s,ElemType t){
	int i,j;		//定义在外面后面要用
	if(s <= t || L.length == 0)
		return false;
	for(i = 0;i < L.length && L.data[i] < s;i++);
	if(i >= L.length)
		return false;
	for(j = 0;j < L.length && L.data[j] < t;j++);
	for(;j < L.length;i++,j++)
		L.data[i] = L.data[j];
	L.length = i;
	return true;
}

5.从顺序表中删除元素值在s与t之间的所有元素

包含s和t,要求s<t,若s或t不合理或顺序表为空时,显示错误

//分析:	1.排除错误情况
//		2.遍历顺序表
//		3.若为要求元素则
bool DeleteSToT(SqList &L,ElemType s,ElemType t){
	int i,k = 0;	//k用于表示s与t之间元素个数
	if(s >= t || L.length == 0)
		return false;
	for(i = 0;i < L.length;i++){
		if(L.data[i] <= s && L.data[i] >= t){
			L.data[k] = L.data[i]				//删除元素时常用思想:前移
			k++;								//不是要删除的元素就k++,是就不加,与i形成错位
		}
	}
	L.length = k
	return true;
}

6.从有序表中删除所有值重复的元素

使表中所有元素均不同

//分析:	1.遍历表
//		2.设置两个变量j,seek(相当于指针)seek用来在后面不断寻找元素,j用来方便记录前移位置,顺便记录元素个数
//		3.seek变量找到与j变量不同的元素时前移,并j++;相同时j不变,seek继续往下寻找
bool DeleteSame(SqList &L){
	int j = 1;
	int seek = 1;	//寻找下一个不相同的元素
	if(L.length == 0)
		return false;
	for(;seek < L.length;seek++){
		if(L.data[seek] != L.data[seek - 1]){	//这里j也可以是seek-1,都是相同的元素	
			L.data[j + 1] = L.data[seek];	//寻找指针找到不同元素时将元素前移
			j++;
		}
	}
	L.length = j;
}

7.★将两个有序顺序表合并成一个新的有序顺序表

并由函数返回结果顺序表

//分析:	1.排除错误情况:A+B元素长度小于等于C最大长度
//		2.不断取下A,B两个顺序表的表头元素,比较,较小的放入C
//		3.一个表全部比较完后,若A或B还有剩余,全部填至C中
bool Merge(SqList A,SqList B,SqList &C){
	int a = 0,b = 0,c = 0;
	if(A.length + B.length > C.MaxSize)
		return false;
	while(a < A.length && b < B.length){
		if(A.data[a] <= B.data[b])
			C.data[c++] = A.data[a++];
		else
			C.data[c++] = B.data[b++];
	}
	while(a < A.length)
		C.data[c++] = A.data[a++];
	while(b < B.length)
		C.data[c++] = B.data[b++];
	C.length = k;
	return true;
}

8.(难)一个数组A[m+n]中有两个顺序表,将两个顺序表位置互换

bool Reverse(SqList &L,int left,int right){
	int temp;
	for(int i = left;i <=(left + right) / 2;i++){
		temp = L.data[i];
		L.data[i] = L.data[left + rigth - i];
		L.data[left + right - i] = temp;
	}
}
void Exchange(SqList &L,int m,int n){
	Reserve(L,0,m + n - 1);	//对整体
	Reserve(L,0,n - 1);		//对前n个
	Reserve(L,n,m + n - 1);	//对后m个
}

9.顺序表元素递增有序,用最少时间查找数值为x的元素

找到,与后继元素互换;找不到,插入表中并使表仍然有序

//分析:1.折半查找x元素
//2.找到与后一个元素互换
//3.找不到插入右指针下一个位置
void FindX(SqList &L,int x){
	int left,right,mid;
	left = 0,right = L.length - 1;
	while(left <= right){
		mid = (left + right) / 2;
		if(L.data[mid] == x)
			break;
		else if(L.data[mid] < x)
			left = mid + 1;
		else if(L.data[mid] > x)
			right = mid - 1;
	}
	if(L.data[mid] == x && mid != L.length - 1){ //找到x,且x不是最后一个元素(无法交换)
		int temp = L.data[mid];
		L.data[mid] = L.data[mid + 1];
		L.data[mid + 1] = temp;
	}
	if(right < left){		//没找到
		for(int i = L.length - 1;i > right;i--){
			L.data[i + 1] = L.data[i];
		}
		L.data[right + 1] = x;
	}
}

10.将R中序列循环左移p个位置

时间空间尽可能高

void Reverse(int R[],int left,int right){
	for(int i = left;i <= (left + right) / 2;i++){ //从左边遍历到中间
		int temp = R[i];
		R[i] = R[left + right - i];
		R[left + right -1] = temp;
	}
}
void Exchange(int R[],int n,int p){
	Reverse(R,0,n - 1);
	Reverse(R,0,n - p - 1);
	Reverse(R,n - p,n - 1);
}

链表

1.删除不带头结点的单链表L中所有值为x的节点

//分析:1.需要一个p指针指向要删除节点
//2.递归,是x元素,执行操作:p指向该节点,L指向下一个,释放p,继续递归L
//3.不是x元素,继续递归L->next
void DeleteXNode(LinkList &L,ElemType x){
	LNode *p;
	if(L->next == NULL)
		return;
	if(L->data == x){
		p = L;
		L = L->next;
		free(p);
		DeleteXNode(L,x);
	}else
		DeleteXNode(L->next,x);
}

2.单链表L(带头结点),删除所有值为x的节点,并释放其空间

值为x的节点不唯一

//分析:1.三个指针,分别:工作指针,前驱指针,释放节点指针
//2.若是x:q指针指向x,p后移,连接pre与p节点,free(q)
//3.不是x:p,pre后移
void DeleteXNode(LinkList &L,ElemType x){
	LNode *p,*pre,*q;	//分别:工作指针,前驱指针,释放节点指针
	while(p != NULL){
		if(p->data == x){
			q = p;
			p = p->next;
			pre->next = p;
			free(q);
		}else{
			pre = pre->next;
			p = p->next;
		}
	}
}

3.单链表(带头节点)从尾到头反向输出每个节点

//分析:1.递归寻找下一个元素
//2.返回时依次打印输出
void ReversePrint(LinkList L){
	if(L->next == NULL)
		print(L->data);
	else
		ReversePrint(L->next);
}

4.在单链表(带头结点)中删除一个最小值节点

效率高,假设最小值节点唯一

//分析:1.指针:工作遍历指针,前驱指针,指向最小值节点指针;变量:最小值
void DeleteMinNode(LinkList &L){
	LNode *p = L->next,*pre = L,*min = p,*minpre = pre;
	ElemType value = p->data;
	while(p != NULL){
		if(p->data < min->data){
			min = p;
			minpre = pre;
		}
		p = p->next;
		pre = pre->next;
	}
	minpre->next = min->next;
	free(min);
}

5.将带头结点的单链表就地逆置(空间复杂度为O(1))

//分析:断开节点重新连结
//1.初始化:断开头节点,头节点指向NULL
//2.指针:工作指针p处理连结,r指针指向断开后段
//3.重新连结:从p断开,r指向p的下一个,使p指向L的下一个,使L指向p
void ReverseSpaceOne(LinkList &L){
	LNode *p = L->next,r;
	L->next = NULL;
	while(p != NULL){
		r = p->next;
		p->next = L->next;
		L->next = p;
		p = r;
	}
}

6.带头结点的单链表,使其元素递增有序

//分析:断开重新连结并排序
//1.初始化:断开头节点,头节点指向NULL
//2.指针:p工作指针处理连结,r指针指向断开后段,f前段排序指针
//3.重新连结并排序
void UpSort(LinkList L){
	LNode *p = L->next,*r,*f = L;
	L->next = NULL;
	while(p != NULL){
		r = p->next;
		while(f->next->data < p->data && f->next != NULL)
			f = f->next;
		p->next = f->next;
		f->next = p;
		p = r;
	}
}

7.带头结点单链表无序,删除所有介于两个给定值s和t之间的元素

//分析:指针:工作指针p,前驱指针pre
//判断p节点指向值是否要删除
//是删除元素:使r指向节点指向删除节点的下一个节点,释放p节点,再使p指向
//不是删除元素:p,r继续遍历
void DeleteStoT(LinkList &L,ElemType s,ElemType t){
	LNode *p = L->next,*pre = L;
	while(p != NULL){
		if(p->data > s && p->data <t){
			r->next = p->next;
			free(p);
			p = r->next;	
		}else{
			r = p;
			p = p->next;
		}
	}
}

8.两个单链表,找到公共节点

//分析:1.先将长的链表遍历到两链表一样长
//2.两链表开始对比:当前节点的值,若相同则找到;若不相同,继续遍历
//3.指针:long指针,short指针;变量:两链表长度,两链表长度差值
LNode *ShareNode(LinkList L1,LinkList L2){
	LNode *L,*s;
	int len1 = Length(L1),len2 = Length(L2),disp;
	if(len1 < len2)
		disp = len2 - len1;
		L = L2->next;
		S = L1->next;
	if(len1 > len2)
		disp = len1 - len2;
		L = L1->next;
		S = L2->next;
	while(disp != 0) 
		L = L->next;
		disp--;
	while(l != NULL){
		if(L->data == S->data)
			return L;
		else{
			L = L->next;
			S = S->next;	
		}
	}
	return NULL;
}

9.按递增次序输出单链表中各节点的数据元素,并释放节点空间

不使用数组作为辅助空间

//分析:每遍历一次输出一个最小元素
void PrintMin(LinkList &L){
	LNode *p,*min;
	while(L->next != NULL){
		p = L->next;
		min = p;
		while(p->next != NULL){
			if(p->next->data < min->data)
				min = p;
			p = p->next;
		}	
		LNode *x = min->next
		print(x->data);
		min->next = x->next;
		free(x);
	}
	free(L);
}

10.带头结点单链表A,将其中奇数位置元素放在A,偶数在B

//分析:指针:A表指针,B表指针,
//1.odd的下一个元素给x记录下来,odd元素next指向odd的下下个元素
//2.偶数位置元素给B,even指针后移,even指向元素next置为NULL;
LinkList Separate(LinkList &A){
	LinkList B = (LinkList)malloc(sizeof(LNode));
	B->next = NULL;
	LNode *odd = A->next,*even = B,*x;
	while(odd->next != NULL){
		x = odd->next
		odd->next = odd->next->next;
		even->next = x->next;
		even = even->next;
		odd = odd->next;
	}
	even->next = NULL;
	return B;
}

12.递增有序单链表,去掉数值相同元素

//分析:指针:工作指针p
void DeleteSame(LinkList &L){
	LNode *p = L->next,*x;
	while(p != NULL){
		if(p->next->data == p->data){
			x = p->next;
			p->next = x->next;
		free(x);
		}else
			p = p->next;
	}
}

21.查找链表中倒数第K各节点

查找成功输出该节点值,并返回1,否则返回0

//分析:指针:前指针,后指针
//1.后指针先跑k个节点,然后两个指针一块跑,后面指针为空时,前面指针即为倒数第k个元素
//返回值,若count还<k:k超过线性表长度;count=k:查找成功
int SearchK(LinkList L,int k){
	LNode *p = L,*q = L;
	int count = 1;
	while(p != NULL){
		if(count < k)
			count++
		else
			q = q->next;
		p = p->next;	
	}
	if(count < k)
		return 0;
	else{
		printf("%d",q->data);
		return 1;
	}
}

循环链表

18.两个循环链表h1和h2,将h2合并到h1中

//分析:指针:寻找h1的表尾指针,寻找h2的表尾指针
//1.分别遍历寻找h1,h2的表尾
//2.拼接
LinkList Joint(LinkList &h1,LinkList &h2){
	LNode *tail1 = h1,*tail2 = h2;
	while(tail1->next != h1)
		tail1 = tail1->next;
	while(tail2->next != h2)
		tail2 = tail2->next;
	tail1->next = h2->next;
	tail2->next = h1;
	return h1;
}

19.带头结点循环单链表反复找到最小节点输出,并删除

链表为空时,删除表头节点

//分析:指针:工作指针p,前驱指针pre,最小节点指针min
//1.循环遍历,并标记最小节点
//2.修改指针,释放节点;最终释放表头
void DeleteAll(LinkList &L){
	LNode *p ,*pre,*premin,*min;
	while(L->next != L){
		premin = L;
		min = L->next;
		pre = L;
		p = L->next;
		while(p != L){
			if(p->data < min->data){
				min = p;
				premin = pre;
			}
			p = p->next;
			pre = pre->next;
		}
		premin->next = min->next;
		printf("%d",min->data);
		free(min);
	}
	free(L);
}

22.判断一个链表是否有环

如果有环,找出环的入口点并返回;否则返回NULL

//分析:指针:快指针,慢指针
//1.快指针和慢指针再次相遇的时候,说明有环;为NULL说明没环
LNode *SearchEnter(LinkList L){
	LNode *slow = L,*fast = L;
	while(slow != NULL && fast != NULL){
			slow = slow->next;
			fast = fast->next->next;
			if(slow == fast)
				break;
	}
	if(slow == NULL && fast == NULL)
		return NULL;
	..........不会了
}

25.后半部分逆置插入前段部分

//分析:指针:
//1.先找到中间(需要逆置部分的头节点)
//2.就地逆置(断开重新连接)
//3.插入,断开的同时,进行插入操作
void ReverseAndInsert(LinkList &L){
	LNode *p,*q,*r,*l;
	while(p !NULL)
}

1.判断输入输出序列是否为合法序列

//分析:
//1.遍历序列
//2.若是I就i+1,若是O就o+1
//3.特殊情况:入栈过程中入栈次数≥出栈次数,否则返回false
//4.要求栈为空:最终i = o,否则返回false
bool Judge(char A[]){
	int k;
	int i = 0,o = 0;
	while(A[k] != '/0'){
		switch(A[k]){
			case 'I': 
				i++;
				break;
			case 'O':
				o++;
				if(o > i)
					return fasle;
		}
		i++;
	}
	if(o != i)
		return false;
	else
		return true;
}

2.判断链表中n个字符是否中心对称

//分析:
//1.将前半段链表元素进栈,
//2.然后栈每弹出一个元素,就与链表后半段元素比较,相同继续比较,不相同则返回false
//3.直到栈为空,特殊情况:n为奇数时,跳过中间那个,从下一个开始比较
bool Symmetry(LinkList L,int n){
	int top = 0;	//栈内元素个数
	char A[n/2];	//栈
	LNode *p = L->next;
	for(int i = 0; i < n/2;i++){
		A[i] = p->data;
		p = p->next;
	}
	i--;		//指向栈顶元素
	if(n % 2 = 1)
		p = p->next;
	while(p != NULL && A[i] == p->data){
		p = p->next;
		i--;
	}
	if(i == -1)
		return true;
	else
		return false;
}

3.两个栈共享空间

结构定义
#define MaxSize 100
#define ElemType int
typedef struct {
	ElemType A[MaxSize];
	int top
}

栈和队列应用

1.判断表达式中的括号是否匹配问题,‘\0’作为结束符

//分析:1.遇到左括号就入栈;2.遇到右括号,判断括号类型是否与栈顶括号对应
//2.遍历:只有不是括号时,i+1
bool BracketCheck(char str[]){
	int i = 0,x;
	SqStack S;
	InitStack(S);
	while(str[i] != '\0'){
		if(str[i] == '(' || str[i] == '[' || str[i] == '{'){
			Push(S,str[i]);
			break;
		}
		switch(str[i]){
			case ')':
				Pop(S,x);
				if(x != '(')
					return false;
			case ']':
				Pop(S,x);
				if(x != '[')
					return false;
			case '}':
				Pop(S,x);
				if(x != '{')
					return false;
			default:
				break;
		}
		i++;
	}
	if(!EmptyStack(S))
		return false;
	return true;
}
  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
王道数据结构课后中,有一个关于排序的目。根据引用的思路,我们可以使用排序后查找的方法来解决这个问。具体步骤如下: 1. 首先,对给定的数据进行排序,可以使用快速排序、归并排序等常见的排序算法进行排序。排序的时间复杂度为O(log2n)。 2. 排序完成后,我们可以使用二分查找的方法来查找特定元素。如果目标元素存在于排序后的数组中,可以通过遍历判断其是否存在。时间复杂度为O(log2n)。 所以,根据引用的思路,我们可以使用排序后查找的方法来解决王道数据结构课后中排序的问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [leetcode答案-kaoyan-data-structure:21考研,用的去年的书《2020王道数据结构》](https://download.csdn.net/download/weixin_38733733/19920375)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [王道数据结构课后编程(顺序表)](https://blog.csdn.net/RHJlife/article/details/90450834)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java程序员十六

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值