练习数据结构上机题1

链表去重

给定一个键值为整数的单链表 L,将键值的绝对值有重复的结点删除:即对任意键值K,只有键值或其绝对值等于 K 的第一个结点被保留在 L 中。例如,下面单链表L 包含键值21、-15、15、7、-15;去重后的链表 L 包含键值 21、-15、7。

输入说明: 输入的第一行包含两个整数,分别表示链表第一个结点的地址和结点个数n(1≤n≤100)。结点地址是一个非负的 5 位整数,NULL 指针用-1 表示。 随后 n 行,每行含 3 个整数,按下列格式给出一个结点的信息: Address Key Next 其中 Address 是结点的地址,Key 是绝对值不超过 10000 的整数,Next 是下一个结点的地址。输出说明: 输出的第一行为去重后链表 L 的长度,换行;接下来按顺序输出 L 的所有结点,每个结点占一行,按照 Address Key Next 的格式输出,间隔 1 个空格。

1 指针赋地址就是强制转换

2 注意输出格式,0补齐。

 

很久很久之前写的…………只有60分。
#include<stdio.h>
int main()
{
	int node[100000][2] = { 0 };
	int head = 0, num = 0;
	int count = 0, i, k;
	scanf("%d%d", &head, &num);
	for (i = 0; i < num; i++)
	{
		scanf("%d", &k);
		scanf("%d%d", &node[k][0], &node[k][1]);//address, value and next
	}

	for (i = head; node[i][1] != -1&&count<num; i = node[i][1])
	{
		if (node[i][0])
		{
			count++;
			for (k = node[i][1]; node[k][1] != -1; k = node[k][1])
			{
				if (node[i][0] == node[k][0] || node[i][0] == -1 * node[k][0])
					node[k][0] = 0;
			}
		}
	}
	printf("%d\n", count);	//print
	printf("%05d %d ", head, node[head][0]);

	for (i = node[head][1]; node[i][1] != -1; i = node[i][1])
	{
		if ( node[i][0])
			printf("%05d\n%05d %d ", i, i, node[i][0]);
	}
	printf("-1\n");
	return 0;
}

报数出列问题

已知N个人(以编号1,2,3...N分别表示)排成一列, 第一轮从编号为1的人开始依次报数,数到2的倍数的人出列第二轮从头开始依次报数,数到3的倍数的人出列;第三轮再次从头开始依次报数,数到2的倍数的人出列从头开始依次报数,数到3的倍数的人出列规律重复下去,直到队列中的人数不超过三个为止。要求输出此时队列中剩下的人在初始队列中的编号。

使用队列,每次操作时对队列中元素进行判断,不需要舍弃的就重新加入队列;

但是实际上对于一道题而言,用队列很麻烦

#include <iostream>
using namespace std;

int main() {
	int k;
	cin >> k;
	int a[k + 1] = {0};
	int sum = k;
	int t;
	for (int flag = 0; sum > 3; flag++) {//每执行一次这个循环,2倍数或3倍数的人出列
		//flag为双数,2倍数出列;为奇数,3倍数出列
		t = 0;
		for (int i = 1; i <= k; i++) {//每进行一次这层循环,有0/1个人出列
			if (a[i] == 0) {//数组值为0说明还没有出列,1说明出列了
				t++;//t是队列剩余人数中,当前遍历到的人的编号
			}
			if (flag % 2 == 0 && t % 2 == 0 && a[i] == 0) {
				a[i] = 1;
				sum--;
			} else if (flag % 2 == 1 && t % 3 == 0 && a[i] == 0) {
				a[i] = 1;
				sum--;
			}
		}
	}
	for (int i = 1; i <= k; i++) {
		if (a[i] == 0)
			cout << i << " ";
	}
	return 0;
}

奇偶序列

输入一个整数组成的序列,然后将序列中的奇数位置结点依序放在前面,偶数位置结点依序放在后面,组成一个新的序列。输出此新序列。

#include<stdio.h>

int main()
{
	int n;scanf("%d",&n);
	int even[100]={0},odd[100]={0};
	int e=0,o=0;
	for(int i=1;i<=n;i++)
	{
		if(i%2){
			scanf("%d",&odd[o]);o++;
		}
		else {
			scanf("%d",&even[e]);e++;
		}
	}
	for(int i=0;i<o;i++)
		printf("%d ",odd[i]);
	for(int i=0;i<e;i++)
		printf("%d ",even[i]);
	return 1;
}

有序表的合并去重

已知两个有序线性表L1和L2,每个线性表中数据元素的值为单调增的正整数(<100个),各线性表内部无重复元素。把L2中的元素合并到L1中,要求L1中数据元素的值仍为单调递增,无重复元素。

#include<stdio.h>
int main()
{
	int n1,n2;scanf("%d%d",&n1,&n2);
	int a[200]={0};
	for(int i=0;i<(n1+n2);i++)
		scanf("%d",&a[i]);
	//起泡排序
	int flog,i,j,t;
	for(i=0;i<(n1+n2);i++)
	{
		flog=1;
		for(j=n1+n2-1;j>i;j--)
		{
			if(a[j-1]>a[j])
			{
				t=a[j];a[j]=a[j-1];a[j-1]=t;
				flog=0;
			}
		}
		if(flog)
		break;
	 } 
	 printf("%d ",a[0]);
	 for(i=1;i<(n1+n2);i++)
	 {
	 	if(a[i]==a[i-1])
		 	continue;
		else printf("%d ",a[i]);
	 }
	return 1;
 } 

最小周期串

如果一个字符串可以由某个长度为k的字符串重复多次得到,我们说该串以k为周期。例如,abcabcabcabc以3为周期(注意,它也以6和12为周期)。输入一个长度不超过80的串,输出它的最小周期。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	char str[100]={0};
	scanf("%s",str);
	int len=strlen(str);//长度 
	for(int i=1;i<=len;i++)//从小到大逐个尝试最小周期
	{//注意一点i要取等号 
		int flog=1;
		for(int j=i;flog&&j<len;j++)
		{//直接求周期不好求,方法就是穷举 
			if(str[j]!=str[j-i])
				flog=0;	
		}	
		if(flog)
		{
			printf("%d",i);return 0;
		}
	} 
	
}

顺寻串的next函数

next函数就是:管你理解不理解,背过就完事了

void get_next(char str[],int next){
    i=1;next[1]=0;j=0;
    while(i<str[0]){
        第0位记录长度
        if(j==0||str[i]==str[j]){i++;j++;next[i]=j;}
        else j=next[j]
    }
}

判断栈序列

如果以序列“1,2,3,4”作为一个栈(初始为空)的输入,那么可得到输出序列“1,2,3,4”或“4,3,2,1”或“2,3,1,4”等等,但是肯定得不到输出序列“4,1,2,3”或“3,1,2,4”等等。请编写一个程序,判断能否通过一个栈得到给定的输出序列。

逐个入栈->如果栈顶和所给序列相同->出栈|||->如果栈顶和所给序列不同->继续入栈

#include<iostream>
#include<stack>
using namespace std;

int main()
{
	int n;scanf("%d",&n);
	int a[100]={0};
	for(int i=0;i<n;i++)
		scanf("%d",&a[i]);
	stack<int>b;
	int j=0;
	for(int i=1;i<=n;i++)
	{
		b.push(i);
		while(j<n)
		{
			if(b.empty())	break;//一定一定一定要有这个 
			if(b.top()==a[j])
			{
				b.pop();
				j++;
			 }
			 else break; 	
		}
	}
	//yes:当遍历完原序列时,恰好stack也全部出栈了 。 
	//no:stack有无法出栈的。 
	if(b.empty())
	printf("yes");
	else
	printf("no");
	return 1;
}

后缀表达式、前缀表达式、括号匹配

数据结构题C语言:栈的练习_NI3E-CSDN博客_c语言栈题目

矩阵加法

 

 看着花里胡哨,思路大概就是:输入的矩阵+数字转化成正常的矩阵,然后逐个相加并最后输出结果,结果也要改成花里胡哨的。

#include<stdio.h>
int main()
{
	int row, col;
	scanf_s("%d%d", &row, &col);
	int a[100][100] = { 0 },b[100][100]={ 0 };
	/*输入第一个矩阵*/
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			scanf_s("%d", &a[i][j]);
	}
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			if (a[i][j])
				scanf_s("%d", &a[i][j]);
	}
	/*输入第二个矩阵*/
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			scanf_s("%d", &b[i][j]);
	}
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			if (b[i][j])
				scanf_s("%d", &b[i][j]);
	}
	/*输出结果*/
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (a[i][j] + b[i][j])
				printf("1 ");
			else
				printf("0 ");
		}
		printf("\n");
	}
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
			if (a[i][j] + b[i][j])
				printf("%d ",a[i][j]+b[i][j]);
	}
	return 1;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值