数据结构与算法题目集PTA

这篇博客介绍了多种数据结构和算法操作,包括单链表的逆转、顺序表操作、链式表的表长计算、按序号查找、链式表操作集、堆栈实现、二叉树高度计算、二分查找以及二叉搜索树操作。这些内容涵盖了基础数据结构的使用和常见算法的实现,对于理解数据结构和算法有着重要作用。
摘要由CSDN通过智能技术生成

6-1 单链表逆转

注意审题,是对原表进行改变,而不是创建一个新表进行逆值。所以逆值后输出原表时,直接输出尾节点。
List Reverse( List L ){
	List s,head = (struct Node*)malloc(sizeof(struct Node));
	head->Next = NULL;
	while( L!= NULL){
		s = L->Next;
		L->Next = head->Next;
		head->Next = L;
		L = s;
	}
	
	return head->Next;
	
}

6-2 顺序表操作集

链接中的代码,我加了测试环节可以下载测试一下

创建空表,Last初始值为-1		//Last 指向的是数组中的最后一个元素的下标,并非长度
List MakeEmpty(){
	List L;
	L = (struct LNode*)malloc(sizeof(struct LNode));
	L->Last = -1;
	return L;
}

// 返回线性表中X的位置。若找不到则返回ERROR;
Position Find( List L, ElementType X ){
	for(int i=0;i<=L->Last;i++){
		if(L->Data[i] == X){
			return i;
		}
	}
	return ERROR;
}

// 插入操作
bool Insert( List L, ElementType X, Position P ){
	if(L->Last == MAXSIZE-1){
		printf("FULL");
		return false;
	}	
	else if( P < 0 || P > L->Last+1){
		printf("ILLEGAL POSITION");
		return false;
	}
	else{
		for(int i=L->Last;i>=P;i--){
			L->Data[i+1] = L->Data[i];
		}
		L->Data[P] = X;
		L->Last++;
	}
	return true;
}

// 删除操作
bool Delete( List L, Position P ){
	if( P < 0 || P > L->Last){
		printf("POSITION %d EMPTY",P);
		return false;
	}
	for(int i=P;i<L->Last;i++){		//表长为0时,不仅循环直接减,变成-1
		L->Data[i] = L->Data[i+1];
	}
	L->Last--;
	return true;
}

6-3 求链式表的表长

采用头插法,不带头节点

读表,
没有啥难度,不做解释了
List Read(){
	List head, s;
	ElementType data;
	head = NULL;
	scanf("%d",&data);
	while(data != -1){
		s = (struct LNode*)malloc(sizeof(struct LNode));
		s->Data = data;
		s->Next = head;
		head = s;
		scanf("%d",&data);
	}
	return head;
}

// 计算表长度
int Length( List L ){
	int sum = 0;
	while(L != NULL){
		sum++;
		L = L->Next;
	}
	return sum;
}

6-4 链式表的按序号查找

 读表,采用尾插法,不带头节点
List Read(){
	List head,rear,s,temp;	// head头节点 rear尾结点 s插入节点
	int data;
	scanf("%d", &data);	//因为不带头节点所以头节点要特殊判断
	if(data == -1){		//表空
		return NULL;
	}
	head = (struct LNode*)malloc(sizeof(struct LNode));
	head->Data = data;
	rear = head;
	scanf("%d", &data);
	while(data != -1){
		s = (struct LNode*)malloc(sizeof(struct LNode));
		s->Data = data;
		rear->Next = s;
		rear = s;
		scanf("%d", &data);
	}
	rear->Next = NULL;	// 最后一个节点加空NUll
	temp = head;
	while(temp != NULL){
		printf(" %d ",temp->Data);
		temp = temp->Next;
	}
	printf("\n");
	return head;
}


// 查找元素
 注意K的取值范围,注意L是否为空
ElementType FindKth( List L, int K ){
	if(K <= 0){
		return ERROR;
	}
	while(K>1&& L!=NULL){
		L = L->Next;
		K--;
	}
	if(L == NULL){
		return ERROR;
	}
	return L->Data;
}

6-5 链式表操作集

 查找函数-------返回线性表中首次出现X的位置。若找不到则返回ERROR
Position Find( List L, ElementType X ){
	while(L != NULL){
		if(L->Data == X){
			return L;
		}
		L = L->Next;
	}
	return ERROR;
}

 插入函数-----将X插入在位置P指向的结点之前,返回链表的表头
 如果参数P指向非法位置,则打印“Wrong Position for Insertion”,返回ERROR;
List Insert( List L, ElementType X, Position P ){
	Position s,rear = L;
	if(L == NULL && P == NULL){		//表空时,插入第一个节点
		L = (struct LNode*)malloc(sizeof(struct LNode));
		L->Data = X;
		L->Next = NULL;
		return L;
	}
	if(L == P){			//		头节点插入
		s = (struct LNode*)malloc(sizeof(struct LNode));
		s->Data = X;
		s->Next = L;
		L = s;
		return L;
	}
	while(rear != NULL){
		if(rear->Next == P){
			s = (struct LNode*)malloc(sizeof(struct LNode));
			s->Data = X;
			s->Next = P;
			rear->Next = s;
			return L;
		}
		rear = rear->Next;
	}
	printf("Wrong Position for Insertion\n");
	return ERROR;
	
}

 删除函数----- 将位置P的元素删除并返回链表的表头
 若参数P指向非法位置,则打印“Wrong Position for Deletion”并返回ERROR
List Delete( List L, Position P ){
	Position head = L,rear = head->Next;
	if(P != NULL){	// P 节点有值时
		if(L == P){		// 第一个节点时,直接删除
			return L->Next;
		}
		while(rear != NULL){ //删除指定节点,设置2个指针,一个指向P,一个指向P的前节点
			if( rear == P){
				head->Next = rear->Next;
				free(rear);
				return L;
			}
			head = head->Next;
			rear = rear->Next;
		}
	}
	printf("Wrong Position for Deletion\n");
	return ERROR;
}

6-6 带头结点的链式表操作集

 创建并返回一个空的线性表
List MakeEmpty(){
	List head;
	head = (struct LNode *)malloc(sizeof(struct LNode));
	head->Next = NULL;
	return head;
}

 返回线性表中X的位置。若找不到则返回ERROR
Position Find( List L, ElementType X ){
	Position head = L->Next; // 第一个节点
	while(head != NULL){
		if(head->Data == X){
			return head;
		}
		head = head->Next;
	}
	return ERROR;
}

 将X插入在位置P指向的结点之前,返回true ****还是头插法****
 如果参数P指向非法位置,则打印Wrong Position for Insertion返回false
bool Insert( List L, ElementType X, Position P ){
	Position s,rear = L;
		if(L->Next == NULL && P == NULL){	//插入第1个节点
			s = (struct LNode*)malloc(sizeof(struct LNode));
			s->Data = X;
			s->Next = NULL;
			L->Next = s;
			return true;
		}
		while(rear != NULL){	//设置1个指针,rear->next指针比较,相等时,将新结点插入rear后 rear->next之前
			if(rear->Next == P){
				s = (struct LNode*)malloc(sizeof(struct LNode));
				s->Data = X;
				rear->Next = s;
				s->Next = P;
				return true;
			}
			rear = rear->Next;
		}
		printf("Wrong Position for Insertion\n");
		return false;
}


 将位置P的元素删除并返回true。
 若参数P指向非法位置,则打印Wrong Position for Deletion并返回false
bool Delete( List L, Position P ){
	Position head=L,rear = L->Next;
	if(P != NULL){
		while(rear != NULL){	//设置两个指针 1前1后,后面的指针比较,相等时,删除后结点,连接后后结点
			if(rear == P){
				head->Next = rear->Next;
				free(P);
				return true;
			}
			head = head->Next;
			rear = rear->Next;
		}
	}
	printf("Wrong Position for Deletion\n");
	return false;
}

6-7 在一个数组中实现两个堆栈

共享栈
不要粗心大意,千万要小心,题目的要求
1.数组为空的情况、2.两个栈的设置、3.栈满、栈空的设置
PTA的审题标准不是很严,所以没有考虑到代码的健壮性,如果你想当你一名合格的程序猿,就要去考虑,可能出错的情况。
我附加了测试的代码,可以看一下,不过输入方式和pta不同,自行分析。不难

	这里和PTA上给的代码不同,不能按样例输入,自行看代码,此代码不难
Operation GetOp(){
	int n;
	while(1){
		printf("1.PUSH 2.POP 3.END,请输入代码:\n");
		scanf("%d",&n);
		switch (n) {
		case 1:
			return push; 
		case 2:
			return pop;
		case 3:
			return end;
		}
		printf("输入错误!\n");
	}
	
}	
// 打印输出 指定栈
void PrintStack( Stack S, int Tag ){
	int n;
	if(Tag == 1){
		n = S->Top1;
		printf("Pop from Stack %d:",Tag);
		while(n >= 0){
			printf(" %d",S->Data[n]);
			n--;
		}
	}
	else if(Tag == 2){
		n = S->Top2;
		printf("Pop from Stack %d:",Tag);
		while(n < S->MaxSize){
			printf(" %d",S->Data[n]);
			n++;
		}
	}
	printf("\n");
}

Stack CreateStack( int MaxSize ){	//两个栈,分别在数组两端
	Stack s;
	if(MaxSize <= 0){
		return NULL;
	}
	s = (struct SNode*)malloc(sizeof(struct SNode));
	s->Data = (ElementType*)malloc(sizeof(ElementType)*MaxSize);
	s->Top1 = -1;
	s->Top2 = MaxSize;
	s->MaxSize = MaxSize;
	return s;
}

// 入栈------S 为空时要考虑
bool Push( Stack S, ElementType X, int Tag ){
	if(S == NULL){		// 这里我没想到,所以一定要注意细节
		return false;
	}
	if(S->Top2 - S->Top1 == 1){	//	栈满
		printf("Stack Full\n");
		return false;
	}
	if(Tag == 1){
		S->Top1++;
		S->Data[S->Top1] = X;
	}else if(Tag == 2){
		S->Top2--;
		S->Data[S->Top2] = X;
	}
	return true;
}


// 出栈
ElementType Pop( Stack S, int Tag ){
	ElementType temp;
	if(S == NULL){			//注意栈空的情况
		return ERROR;
	}
	if(Tag == 1 ){
		if(S->Top1 == -1){
			printf("Stack %d Empty\n",Tag);
			return ERROR;
		}
		temp = S->Data[S->Top1];
		S->Top1--;
		return temp;
	}
	else if(Tag == 2){
		if(S->Top2 == S->MaxSize){
			printf("Stack %d Empty\n",Tag);
			return ERROR;
		}
		temp = S->Data[S->Top2];
		S->Top2++;
		return temp;
	}
	return ERROR;
}

最后附上效果图:在这里插入图片描述

6-8 求二叉树高度

递归查找 ,返回左右子树中更深的

int GetHeight( BinTree BT ){
	int h1 = 0;
	int h2 = 0;
	if(!BT)
		return 0;
		else{
		h1 = GetHeight(BT->Left);
		h2 = GetHeight(BT->Right);
        if(h1>h2)
           return ++h1;
        else 
           return ++h2;
	}
}

6-9 二叉树的遍历

6-10 二分查找

插入数据的函数:不要求
List ReadInput(){
	int n,i = 0,data;
	List L = (struct LNode*)malloc(sizeof(struct LNode));
	L->Last = 0;	// 一开始值为空
	printf("你想要几个数并创建多大的数组:");
	scanf("%d",&n);
	while(n--){
		scanf("%d",&data);
		i = L->Last;
		while(i>=1){
			if(data < L->Data[i]){		// 直接插入排序
				L->Data[i+1] = L->Data[i];
				i--;
			}
			else
				break;
		}
		i++;
		L->Data[i] = data;
		L->Last++;
	}
/*
	查看插入是否正确
*/
	for(int i=1;i<=L->Last;i++){
		printf(" %d ",L->Data[i]);
	}
	printf("\n");
	return L;
}
Position BinarySearch( List L, ElementType X ){
	int head = 1,  rear = L->Last;
	while(head <= rear){	// head <= rear 查找
		if(X == L->Data[(head+rear)/2]){	//中间比较 相等返回
			return (head+rear)/2;
		}
		else if(X < L->Data[(head+rear)/2]){	// 小于上半部分
			rear = (head+rear)/2-1;
		}
		else {	// 大于上半部分
			head = (head+rear)/2+1;
		}
	}
	return NotFound;
}

6-11 先序输出叶结点

void PreorderPrintLeaves( BinTree BT ){
    if(BT != NULL){	
        if(BT->Left == NULL && BT->Right == NULL)		// 叶节点输出
            printf(" %c",BT->Data);
        if(BT->Left != NULL)	// 左孩子-非叶节点递归,向下查找叶节点
        PreorderPrintLeaves(BT->Left);
        if(BT->Right != NULL)	// 右孩子-非叶节点递归,向下查找叶节点
        PreorderPrintLeaves(BT->Right);
    }
}

6-12 二叉搜索树的操作集

停更22-6-10—22-11-27日-工作后的感触

		刚毕业,找的工作比较不理想,不是研发,生活和心态搞得不是很好
		毕业后一直没有动力再去学习
		所以劝各位在校生
		本科一定要努力学好本专业知识,多参加竞赛,多拿奖!希望以后顺利吧。
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值