(第三章、第二章)数据结构总复习+错题+一些不清楚的点。

(第三章、第二章)数据结构总复习+错题+一些不清楚的点。

第三章栈和队列
  • 慕课:

    • 递归需要终止部分和递归部分
    • 递归比非递归更浪费空间且更慢。
栈混洗的判断,需要的栈的最大容量。
  • 手动判断即可。
各种算法
1.舞伴问题(队列)
  • 还是比较简单的,注意字符串和字符的接收之间的吸收
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<queue>
#include<stack>
using namespace std;
typedef struct
{
	char name[20];
	char sex;
}Datatype;

void DancerFriends(Datatype dancer[20])
{
	queue<Datatype>man;
	queue<Datatype>woman;
	for (int i = 0; i < 9; i++)
	{
		if (dancer[i].sex == 'F')woman.push(dancer[i]);
		else man.push(dancer[i]);
	}
	while (!man.empty() && !woman.empty())
	{
		printf("%s %s\n", woman.front().name, man.front().name);
		man.pop();
		woman.pop();
	}
	while (!man.empty())
	{
		printf("%s\n", man.front().name);
		man.pop();
	}
	while (!woman.empty())
	{
		printf("%s\n", woman.front().name);
	}
}
int main()
{
	Datatype dancer[20];//F为女,M为男
	for (int i = 0; i < 9; i++)
	{
		scanf("%s", dancer[i].name);
		getchar();
		scanf("%c", &dancer[i].sex);
        getchar();//这个可有可不有
	}
	DancerFriends(dancer);
	return 0;
}
/*
李敏浩 M
李钟硕 M
高欣雅 F
吴彦祖 M
王思聪 M
张甜源 F
张智霖 M
许丹丹 F
马小云 F
*/
2.回文问题(栈和队列)
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;

void ChargeHuiWen(char* string)
{
	stack<char>lstack;
	queue<char>lqueue;
	int len = strlen(string);
	int i = 0;
	for (i; i < len; i++)
	{
		lstack.push(string[i]);
		lqueue.push(string[i]);
	}
	while (!lstack.empty() && !lqueue.empty())
	{
		if (lstack.top() == lqueue.front())
		{
			lstack.pop();
			lqueue.pop();
		}
		else
		{
			printf("NO!\n");
			return;
		}
	}
	printf("OK!\n");
}

int main()
{
	char string[20];
	scanf("%s", string);
	ChargeHuiWen(string);
	return 0;
}
3.括号匹配(栈)
  • 注意:与回文问题不一样,只是要求括号的闭合。
  • {{{((()))}}}:这个不是回文 ,{()()()}:这个不是回文,但两个都是ture.(不知道为啥总想把第一个当作回文,但不是啊!!)😿
  • 思路:左括号入栈,右括号比较,比较后出栈。
  • 别忘了考虑最后有剩余的’(‘或’)’
  • 注意用右括号与左括号对应时,不要用输入的右括号与栈里的左括号比啊!。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<queue>
#include<stack>
using namespace std;
int main()
{
	char ch;
	scanf("%c", &ch);
	stack<char>lstack;
	while (ch != '#')
	{
		switch (ch)
		{
		case'[':
		case'(':
		case'{':
			lstack.push(ch);
			break;
		case')':
			if (!lstack.empty())
			{
				if ('(' == lstack.top())
				{
					lstack.pop();
				}
				else
				{
					printf("NO!\n");
					return 0;
				}
			}
			else
			{
				printf("NO!\n");
				return 0;
			}
			break;
		case']':
			if (!lstack.empty())
			{
				if ('[' == lstack.top())
				{
					lstack.pop();
				}
				else
				{
					printf("NO!\n");
					return 0;
				}
			}
			else
			{
				printf("NO!\n");
				return 0;
			}
			break;
		case'}':
			if (!lstack.empty())
			{
				if ('{' == lstack.top())
				{
					lstack.pop();
				}
				else
				{
					printf("NO!\n");
					return 0;
				}
			}
			else//最后剩余右')'
			{
				printf("NO!\n");
				return 0;
			}
			break;
		}
		scanf("%c", &ch);//别忘了。。。
	}
	if (!lstack.empty())//最后有剩余的左括号
		printf("NO!\n");
	else printf("YES!\n");
	return 0;
}
/*测试用例
()()()#
({[]})#
((()))#
({}{})#
({}{}))#
(({}{})#
*/
4.十进制转十六进制(栈)
  • 跟10进制转2进制一个原理,一直短除取余,最后倒过来写。
  • 注意pop,注意除。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<queue>
#include<stack>
using namespace std;

int main()
{
	int temp;
	scanf("%d", &temp);
	stack<int>lstack;
	while (temp != 0)
	{
		lstack.push(temp % 16);
		temp /= 16;
	}
	while (!lstack.empty())
	{
		temp = lstack.top();
		lstack.pop();
		switch(temp)
		{
		case 10:printf("A");
			break;
		case 11:printf("B");
			break;
		case 12:printf("C");
			break;
		case 13:printf("D");
			break;
		case 14:printf("E");
			break;
		case 15:printf("F");
			break;
		default:
			printf("%d", temp);
		}
	}
	return 0;
}
第二章 链表和线性表
  • 慕课

    • 注意给的字母是指针还是数据。。。
    • 双向链表的优点是很方便的插入和删除数据。
顺序表算法

创建空顺序表、输入数据、(判空判满不单独写函数了)、插入某个位置前、插入某个位置后、查找元素某个元素的位置、删除某个位置元素、删除某个元素以及之后的连续几个元素、删除表中所有值为x的元素、删除某个位置到某个位置的元素。(这里的位置我按照从1开始)

🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰🔰

打印函数和主函数:
void print(Seqlist list)
{
	for (int i = 0; i < list->n; i++)
	{
		printf("%d ", list->elem[i]);
	}
	printf("\n");
}
int main()
{
	int max,location,location2;
	Datatype data;
	int len;
	printf("Please input the seq max\n");
	scanf("%d", &max);
	Seqlist list = CreatNullList(max);
	
	Input_data(list);//-1为标志
	print(list);
	
	//printf("input the location and data you want to insert\n");
	//scanf("%d %d", &location,&data);
	
	//Insert_belocation(list, location, data);//在location前插入。
	//print(list);
	
	//Insert_aflocation(list, location, data);//在location后插入。
	//print(list);
	

	//printf("input the data that you want to find\n");
	//scanf("%d", &data);
	//Search(list, data);

	//printf("input the location you want to delete\n");
	//scanf("%d", &location);
	//Delete_1(list, location);
	//print(list);
	
	//printf("input the data and len you want to delete\n");
	//scanf("%d %d", &data, &len);
	//Delete_2(list,data,len);
	//print(list);

	//printf("input the data you want to delete\n");
	//scanf("%d", &data);
	//Delete_3(list, data);
	//print(list);

	printf("input the location and location you want to delete\n");
	scanf("%d %d", &location, &location2);
	Delete_4(list, location, location2);
	print(list);

	return 0;
}
输入数据(以-1截止)
void Input_data(Seqlist list)
{
	Datatype temp;
	printf("please input data\n");
	scanf("%d", &temp);
	for (int i = 0; i < list->max; i++)
	{
		if (temp == -1) break;//-1为结束标志
		list->elem[i] = temp;
		list->n++;
		scanf("%d", &temp);
	}

}
插在某个位置前:
void Insert_belocation(Seqlist list,int location,Datatype data )//插在某个位置前
{
	int i = 0;
	if (list->n >= list->max)
	{
		printf("NO!I am full!!\n");
		return;
	}
	for (i = list->n; i >= location; i--)//注意用减的时候的判断得是大于啊!
	{
		list->elem[i] = list->elem[i-1];//i-1的位置腾出来
	}
	list->elem[i] = data;//最后的循环结束,再i--,刚好是腾出来的位置。
	list->n++;
}
/*数据:
20
1 2 3 4 5 6 -1
6 7

20
1 2 3 4 5 6 -1
5 8

20
1 2 3 4 5 6 -1
1 3
*/
插在某个位置后(其实就是比上一个对location的判断少一个等于)
void Insert_aflocation(Seqlist list, int location, Datatype data)//插在某个位置后
{
	int i = 0;
	if (list->n >= list->max)
	{
		printf("NO!I am full!!\n");
		return;
	}

	for (i = list->n; i > location; i--)
	{
		list->elem[i] = list->elem[i - 1];
	}
	list->elem[i] = data;
	list->n++;
}
/*数据:
20
1 2 3 4 5 6 -1
6 7

20
1 2 3 4 5 6 -1
5 8

20
1 2 3 4 5 6 -1
1 3
*/
寻找某个元素的位置
void Search(Seqlist list, Datatype data)
{
	int i = 0;
	int flag = 0;//表明有没有查到
	for (i = 0; i < list->n; i++)
	{
		if (data == list->elem[i])
		{
			printf("the location is %d\n", i+1);
			flag = 1;
		}
	}
	if (flag == 0)printf("NO,it is not exist\n");
}
/*
20
1 2 2 3 4 5 6 7 -1
2

20
1 2 2 3 4 5 6 7 -1
8
*/
删除某个位置元素(没检测是否存在这个位置)
void Delete_1(Seqlist list, int location)
{
	int i = 0;
	if (location == list->n - 1)
		list->n--;
	else
	{
		for (i = location-1; i < list->n-1; i++)
		{
			list->elem[i] = list->elem[i+1];
		}
		list->n--;
	}
}
/*
20
1 2 3 4 5 6 -1
6

20
1 2 3 4 5 6 -1
1

20
1 2 3 4 5 6 -1
3
*/
删除某个元素以及之后的连续几个元素
void Delete_2(Seqlist list, Datatype data, int len)
{
	int i;
	int del_len = len + 1;
	for (i = 0; i < list->n; i++)
	{
		if (list->elem[i] == data) break;
	}
	if (i + len >= list->n - 1)//也就是从i包括i,以后的元素都被删了
	{
		list->n = i;
	}
	else
	{
		for (int j = i;j+del_len<list->n; j++)
		{
			list->elem[j] = list->elem[j + del_len];
		}
		list->n -= del_len;
	}
}
/*
20
1 2 3 4 5 6 7 -1
3 2

20
1 2 3 4 5 6 7 -1
3 9

20
1 2 3 4 5 6 7 -1
7 0

*/
删除表中所有值为x的元素

注意:这里出现过错误,经调试才发现。

void Delete_3(Seqlist list, Datatype data)//搜索与单个删除的结合
{
	void print(Seqlist list);
	int i = 0;
	int flag = 0;//表明有没有查到
	for (i = 0; i < list->n; i++)
	{
		if (data == list->elem[i])
		{
			Delete_1(list, i+1);
			i--;//都往前挪了,i不可以加!!!!注意,这里出现过错误,经调试才发觉。
			//print(list);
			flag = 1;
		}
	}
	if (flag == 0)printf("NO,it is not exist\n");
}
/*
20
1 2 2 2 2 3 2 2 4 -1
2

20 
1 2 2 2 2 3 4 -1
5
*/
删除某个位置到某个位置的元素。
void Delete_4(Seqlist list, int location1, int location2)
{
	int len = location2 - location1+1;
	if (location2 >= list->n)//从location1开始全删了
	{
		list->n = location1-1;//这里注意减1才是正确的数量,之前那个删除某个元素不用是因为找的是以0为开始的位置,没有改成为1的。
	}
	else
	{
		for (int i = location1 - 1; i + len < list->n; i++)
		{
			list->elem[i] = list->elem[i + len];
		}
		list->n -= len;
	}
}
/*
20
1 2 3 4 5 6 7 -1
3 9

20
1 2 3 4 5 6 7 -1
2 6
*/
链表算法

创建空顺序表、输入数据、(判空判满不单独写函数了)、插入某个元素前、插入某个元素后、删除某个位置元素、删除某个元素以及之后的连续几个元素、删除表中所有值为x的元素、删除某个位置到某个位置的元素。(这里的位置我按照从1开始)

打印函数和主函数:

输入数据(以-1为截止)(尾插法)(注意容易忘记的地方)
void Input(PNode head)//尾插法
{
	PNode q = head;
	int data;
	scanf("%d", &data);
	while (data != -1)
	{
		PNode p = (PNode)malloc(sizeof(struct Node));
		p->data = data;
		p->next = NULL;
		q->next = p;
		q = p;
		scanf("%d", &data);//别忘了,上次的顺序表就也忘了一次加这个!
	}
}

插入到某个元素前
void Insert_pr(PNode head, Datatype data1, Datatype data2)//1判断,2是插入的元素,这个是插在1前面。
{
	PNode p = head->next;
	PNode q = head;
	PNode temp = NULL;
	temp = (PNode)malloc(sizeof(struct Node));
	temp->data = data2;
	temp->next = NULL;
	while (p != NULL)
	{
		if (p->data == data1) break;//注意,不能放在while的判断里,否则NULL是会触发空指针访问
		q = p;
		p = p->next;
	}
	if (p!=NULL)
	{
		q->next = temp;
		temp->next = p;
		return;
	}
}
插入到某个元素后(跟上一个很像,删删改改就好)
void Insert_af(PNode head, Datatype data1, Datatype data2)//1判断,2是插入的元素,这个是插在1后面。
{
	PNode p = head->next;
	PNode temp = NULL;
	temp = (PNode)malloc(sizeof(struct Node));
	temp->data = data2;
	temp->next = NULL;
	while (p != NULL)
	{
		if (p->data == data1) break;//注意,不能放在while的判断里,否则NULL是会触发空指针访问
		p = p->next;
	}
	if (p != NULL)
	{
		temp->next = p->next;
		p->next = temp;
		return;
	}
}
删除某个位置元素(没考虑不存在)
void Del_lin(PNode head, int location)
{
	PNode p = head;
	PNode q = p;
	while (location > 0)
	{
		q = p;
		p = p->next;
		location--;
	}
	q->next = p->next;
	free(p);
}
删除某个元素以及之后的连续几个元素
void Del_c_l(PNode head, Datatype charge, int len)
{
	PNode p = head->next;
	PNode q = head;
	len += 1;//共删除len+chage data=len+1个元素
	while (p != NULL)
	{
		if (p->data == charge) break;
		q = p;
		p = p->next;
	}
	while (p != NULL&&len>0)
	{
		q->next = p->next;
		free(p);
		if (q->next != NULL)
		{
			p = q->next;
			len--;
		}
		else
		{
			q->next = NULL;
			break;
		}
	}
}
删除表中所有值为x的元素
void Del_c_a(PNode head, Datatype data)
{
	PNode p = head->next;
	PNode q = head;
	while (p != NULL)
	{
		if (p->data == data)
		{
			q->next = p->next;
			free(p);
			p = q->next;
		}
		else
		{
			q = p;
			p = p->next;
		}
	}
}
删除某个位置到某个位置的元素
void Del_location_2(PNode head, int location1, int location2)
{
	PNode p, q;
	p = head;
	q = head;
	while (location1 > 0&&p!=NULL)
	{
		q = p;
		p = p->next;
		location1--;
		location2--;
	}
	location2++;//location1位置上的还需要一次。其实本质是在用删除的次数来循环,del_len=locaton2-location1+1
	while (location2 > 0&&p!=NULL)
	{
		q->next = p->next;
		free(p);
		p = q->next;
		location2--;
	}
}
		len--;
	}
	else
	{
		q->next = NULL;
		break;
	}
}

}


###### 删除表中所有值为x的元素

```c
void Del_c_a(PNode head, Datatype data)
{
	PNode p = head->next;
	PNode q = head;
	while (p != NULL)
	{
		if (p->data == data)
		{
			q->next = p->next;
			free(p);
			p = q->next;
		}
		else
		{
			q = p;
			p = p->next;
		}
	}
}
删除某个位置到某个位置的元素
void Del_location_2(PNode head, int location1, int location2)
{
	PNode p, q;
	p = head;
	q = head;
	while (location1 > 0&&p!=NULL)
	{
		q = p;
		p = p->next;
		location1--;
		location2--;
	}
	location2++;//location1位置上的还需要一次。其实本质是在用删除的次数来循环,del_len=locaton2-location1+1
	while (location2 > 0&&p!=NULL)
	{
		q->next = p->next;
		free(p);
		p = q->next;
		location2--;
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值