作业1
###线性表练习题(数据结构)
5-1
下列代码的功能是返回带头结点的单链表L的逆转链表。
List Reverse( List L )
{
Position Old_head, New_head, Temp;
New_head = NULL;
Old_head = L->Next;
while ( Old_head ) {
Temp = Old_head->Next;
Old_head->Next = New_head;
New_head = Old_head;
Old_head = Temp;
}
L->Next = New_head;
return L;
}
5-2
假设顺序表的长度为 n,
若在位序 1 处删除元素,则需要移动 n-1 个元素;
若在位序 n 处删除元素,则需要移动 0 个元素;
若在位序 i(1≤i≤n) 处删除元素,则需要移动 n-i 个元素。
假设各位序删除元素的概率相同, 则平均需要移动 (n-1)/2 个元素。
5-3
假设顺序表的长度为 n,
若在位序 1 处插入元素,则需要移动 n 个元素;
若在位序 n+1 处插入元素,则需要移动 0 个元素;
若在位序 i(1≤i≤n+1) 处插入元素,则需要移动 n-i+1 个元素。
假设各位序插入元素的概率相同, 则平均需要移动 个元素。
####7-1 一元多项式求导 (20 分)
设计函数求一元多项式的导数。
输入格式:
以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。
输入样例:
3 4 -5 2 6 1 -2 0
输出样例:
12 3 -10 1 6 0
代码:
#include <stdio.h>
int main()
{
int m,n;
int flag=1;
while(scanf("%d %d",&m,&n)!=EOF&&n>0)
{
if(flag==1)
{
printf("%d %d",m*n,n-1);
flag=0;
}
else
{
printf(" %d %d",m*n,n-1);
}
}
if(flag==1)
printf("0 0");
return 0;
}
思路:
xn(n为整数)的一阶导数为n*x(n-1) 这个理解了就会了
7-2 最长连续递增子序列
给定一个顺序存储的线性表,请设计一个算法查找该线性表中最长的连续递增子序列。例如,(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)。
输入格式:
输入第1行给出正整数n(≤10^5)
第2行给出n个整数,其间以空格分隔。
输出格式:
在一行中输出第一次出现的最长连续递增子序列,数字之间用空格分隔,序列结尾不能有多余空格。
输入样例:
15
1 9 2 5 7 3 4 6 8 0 11 15 17 17 10
输出样例:
3 4 6 8
代码:
#include<stdio.h>
#include<string.h>
int a[100005];
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
int st = 0;
int en = 0;
int ans = 0;
int x = 0, y = 0;
while(en < n)
{
en = st;
while(en < n &&((en == st)|| (a[en] > a[en-1])))
{
en++;
}
if(ans < en - st)
{
ans = en - st;
x = st;
y = en-1;
}
st++;
}
for(int i = x; i <= y; i++)
{
if(i == x)
printf("%d", a[i]);
else
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
7-3 喊山
(心疼自己写不出来这题,所以就参考了百度)
一个山头呼喊的声音可以被临近的山头同时听到。题目假设每个山头最多有两个能听到它的临近山头。给定任意一个发出原始信号的山头,本题请你找出这个信号最远能传达到的地方。
输入格式:
输入第一行给出3个正整数n、m和k,其中n(≤10000)是总的山头数(于是假设每个山头从1到n编号)。接下来的m行,每行给出2个不超过n的正整数,数字间用空格分开,分别代表可以听到彼此的两个山头的编号。这里保证每一对山头只被输入一次,不会有重复的关系输入。最后一行给出k(≤10)个不超过n的正整数,数字间用空格分开,代表需要查询的山头的编号。
输出格式:
依次对于输入中的每个被查询的山头,在一行中输出其发出的呼喊能够连锁传达到的最远的那个山头。注意:被输出的首先必须是被查询的个山头能连锁传到的。若这样的山头不只一个,则输出编号最小的那个。若此山头的呼喊无法传到任何其他山头,则输出0。
输入样例:
7 5 4
1 2
2 3
3 1
4 5
5 6
1 4 5 7
输出样例:
2
6
4
0
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
vector <int> moun[10005];
int flag[10005];
int level[10005];
int n, m, k;
int maxx, maxn;
void BFS(int num)
{
maxx=0;maxn=0;
memset(flag, 0, sizeof(flag));
memset(level, -1, sizeof(level));
queue<int> q;
q.push(num);
flag[num]=1;
level[num]=maxx;
while(!q.empty()){
int x = q.front();
q.pop();
for(int j=0;j<moun[x].size();j++){
int i = moun[x][j];
if(flag[i]==0){
flag[i] = 1;
q.push(i);
level[i] = level[x]+1;
if(level[i]>maxx){
maxx = level[i];
maxn = i;
}else if(level[i]==maxx){
if(maxn>i){
maxn = i;
}
}
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
scanf("%d %d %d", &n, &m, &k);
for(int i=0;i<m;i++){
int m1, m2;
scanf("%d %d", &m1, &m2);
moun[m1].push_back(m2);
moun[m2].push_back(m1);
//moun[m1][m2] = 1;
//moun[m2][m1] = 1;
}
for(int i=0;i<k;i++){
int x;
scanf("%d", &x);
BFS(x);
if(maxx==0){
printf("0\n");
}else{
printf("%d\n", maxn);
}
}
return 0;
}
7-4 jmu-ds-顺序表区间元素删除
若一个线性表L采用顺序存储结构存储,其中所有的元素为整数。设计一个算法,删除元素值在[x,y]之间的所有元素,要求算法的时间复杂度为O(n),空间复杂度为O(1)。
输入格式:
三行数据,第一行是顺序表的元素个数,第二行是顺序表的元素,第三行是x和y。
输出格式:
删除元素值在[x,y]之间的所有元素后的顺序表。
输入样例:
10
5 1 9 10 67 12 8 33 6 2
3 10
输出样例:
1 67 12 33 2
代码:
#include <stdio.h>
#include <stdlib.h>
int a[100];
int n;
int main()
{
scanf("%d", &n);
int x,y;
int temp;
int flag=1;
for(int i=1; i<=n; i++)
scanf("%d", &a[i]);
scanf("%d %d", &x, &y);
for(int i=1; i<=n; i++)
{
if(flag)
{
if(a[i]<x||a[i]>y)
{
printf("%d", a[i]);
flag=0;
}
}
else
{
if(a[i]<x||a[i]>y)
printf(" %d",a[i]);
}
}
return 0;
}
7-5 重排链表 (25 分)
给定一个单链表 L1→L2→⋯→Ln−1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln−1→L2→⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (≤10^5)。结点的地址是5位非负整数,NULL地址用−1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address是结点地址;Data是该结点保存的数据,为不超过10^5的正整数;Next是下一结点的地址。题目保证给出的链表上至少有两个结点。
输出格式:
对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。
输入样例:
00100 6
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
输出样例:
68237 6 00100
00100 1 99999
99999 5 12309
12309 2 00000
00000 4 33218
33218 3 -1
代码:
#include<stdio.h>
const int maxn=1e5+10;
struct Node
{
int ad,next,data;
}mes[maxn],ans[maxn];
int main()
{
int f,n,a;
scanf("%d%d",&f,&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a);
scanf("%d%d",&mes[a].data,&mes[a].next);
}
int r=1;
while(f!=-1)
{
ans[r].ad=f;
ans[r++].data=mes[f].data;
//printf("f=%05d\n",f);
f=mes[f].next;
}
for(int i=1;i<r;i++)
{
if(i%2==1)
mes[i]=ans[r-1-i/2];
else
mes[i]=ans[i/2];
}
for(int i=1;i<r-1;i++)
{
printf("%05d %d %05d\n",mes[i].ad,mes[i].data,mes[i+1].ad);
}
printf("%05d %d -1\n",mes[r-1].ad,mes[r-1].data);
return 0;
}
7-6 顺序表的建立及遍历
读入n值及n个整数,建立顺序表并遍历输出。
输入格式:
读入n及n个整数
输出格式:
输出n个整数,以空格分隔(最后一个数的后面没有空格)。
输入样例:
在这里给出一组输入。例如:
4
-3 10 20 78
输出样例:
在这里给出相应的输出。例如:
-3 10 20 78
代码:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define list 10
#define max 10
typedef int Elemtype;
typedef struct sqlist *List;
struct sqlist
{
Elemtype *elem;
int length;
int listsize;
};
void initlist(List L)
{
L->elem=(Elemtype *)malloc(list*sizeof(Elemtype));
L->length=0;
L->listsize=max;
}
void creat(List L)
{
initlist(L);
int i,n;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&L->elem[i]);
L->length++;
if(L->length==L->listsize)
{
int *new_elem = (Elemtype *)malloc((L->listsize+list)*sizeof(Elemtype));
memcpy(new_elem,L->elem,L->length);
L->elem = new_elem;
L->listsize+=list;
}
}
}
void print(List L)
{
for(int i=0; i<L->length;i++)
{
if(i==L->length-1)
printf("%d",L->elem[i]);
else
printf("%d ",L->elem[i]);
}
}
int main()
{
List L = (List)malloc(sizeof(struct sqlist));
initlist(L);
creat(L);
print(L);
return 0;
}