###線性表練習題(數據結構)
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;
}
思路:
x^n(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;
}