数据结构学习随记 发表于 2024-05-13 | 更新于 2024-06-29
| 阅读量:
数据结构 链表 重要题目 6-2 有序链表合并
请编程实现有序链表合并。
函数接口定义:
1 2 3 LinkList Read ( ) ; LinkList Merge ( LinkList L1, LinkList L2 ) ;
参数 L1
和 L2
是两个有序链表(均按照非递减排列),均为带头结点的单链表。
裁判测试程序样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <stdio.h> #include <stdlib.h> typedef int ElemType;typedef struct Node { ElemType data; struct Node *next; }LNode,*LinkList; LinkList Read ( ) ; LinkList Merge ( LinkList L1, LinkList L2 ) ;int main () { LinkList L1, L2, L,p; L1 = Read (); L2 = Read (); L = Merge (L1, L2); if (!L) { printf ("empty" ); return 0 ; } p=L->next; while (p!=NULL ){ printf ("%d " ,p->data); p=p->next; } return 0 ; }
输入样例:
输出样例:
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 LinkList Read ( ) { LinkList L = (LinkList)malloc (sizeof (LNode)); L->next = NULL ; LNode *p, *q; q = L; ElemType x; scanf ("%d " ,&x); while (x != -1 ){ p = (LinkList)malloc (sizeof (LNode)); p->next = NULL ; p->data = x; q->next = p; q = p; scanf ("%d" ,&x); } return L; } LinkList Merge ( LinkList L1, LinkList L2 ) { if (L1->next == NULL && L2->next == NULL ) return NULL ; LinkList L = (LinkList)malloc (sizeof (LNode)); L->next = NULL ; LinkList p = L, p1 = L1->next, p2 = L2->next; while (p1 && p2){ if (p1->data <= p2->data){ p->next = p1; p1 = p1->next; } else { p->next = p2; p2 = p2->next; } p = p->next; } p->next = p1?p1:p2; return L; } }
栈 一些重要知识 两栈共享 数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为栈的末端,即下标为数组长度n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。
关键思路:它们是在数组的两端,向中间靠拢。top1和top2是栈1和栈2的栈顶指针,可以想象,只要他们俩不见面,两个栈就可以一直使用。
重要题目 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 若栈采用顺序存储方式存储,现两栈共享空间V[1..m],top[i]代表第i个栈( i =1,2)栈顶(该位置不存储对应栈数据),栈1的底在v[1],栈2的底在V[m],则栈满的条件是( B )。 A. |top[2]-top[1]|=0 B. top[1]-1=top[2] C. top[1]+top[2]=m D. top[1]=top[2]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 令P代表入栈,O代表出栈。则将一个字符串`3*a+b/c`变为`3 a * b c / +`的堆栈操作序列是哪个?(例如将`ABC`变成`BCA`的操作序列是PPOPOO。) () A. PPPOOOPPOPPOOO B. POPOPOPPOPPOOO C. POPPOOPPOPOOPO D. POPPOOPPOPPOOO
重点在于理解“变为”的意思,即是出栈的顺序,不要理解错误。
队列 复习 链队 记住初始形态,头尾指针都指着一个空节点!s
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Status InitQueue (LinkQueue &Q) { Q.front = Q.rear = new QNode; Q.front->next = NULL ; return OK; } Status EnQueue (LinkQueue &Q, QElemType e) { QueuePtr p; p = new QNode; p->data = e; p->next = NULL ; Q.rear->next = p; Q.rear = p; return OK; } Status DeQueue (LinkQueue &Q, QElemType &e) { QueuePtr p; if (Q.front == Q.rear) return ERROR; p = Q.front->next; e = p->data; Q.front->next = p->next; if (Q.rear == p) Q.rear = Q.front; delete p; return OK; }
重要题目 6-2 循环队列出队入队 分数 20
作者 YJ
单位 西南石油大学
用一个数组表示循环队列,请编写算法实现循环队列的初始化、入队和出队操作。
输入时:第一行输入队列数据空间容量,第二行依次输入5个待插入元素值,第三行再依次输入5个待插入元素值。 输出时:第一行和最后一行输出循环队列元素值及其下标(元素值(下标)),若中途出现队空或队满,则应给出相应提示。
函数接口定义:
1 2 3 void InitQ (SqQueue &Q,int N) ;void AddQ (SqQueue &Q, int x ) ;Status DeleteQ (SqQueue &Q,int &e) ;
接口参数: Q
是循环队列, N
是队列数组空间容量, x
是入队元素, e
用于接收出队元素的值
裁判测试程序样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 #include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 typedef int Status;typedef struct { int *base; int front; int rear; }SqQueue; void InitQ (SqQueue &Q,int N) ;void AddQ (SqQueue &Q, int x ) ;Status DeleteQ (SqQueue &Q,int &e) ;void printQ (SqQueue Q) ; int N;int main () { int x,e,i; SqQueue Q; scanf ("%d" ,&N); InitQ (Q,N); for (i=0 ;i<5 ;i++){ scanf ("%d" ,&x); AddQ (Q,x); } printQ (Q); for (i=0 ;i<5 ;i++){ if (DeleteQ (Q,e)==OK) printf ("%d is out.\n" ,e); } for (i=0 ;i<5 ;i++){ scanf ("%d" ,&x); AddQ (Q,x); } printQ (Q); return 0 ; } void printQ (SqQueue Q) { int i; i=Q.front; while (i!=Q.rear){ printf ("%d(%d) " ,Q.base[i],i); i=(i+1 )%N; } printf ("\n" ); }
输入样例1:
输出样例1:
1 2 3 4 5 6 7 1(0) 2(1) 3(2) 4(3) 5(4) 1 is out. 2 is out. 3 is out. 4 is out. 5 is out. 1(5) 2(0) 3(1) 4(2) 5(3)
输入样例2:
输出样例2:
1 2 3 4 5 6 7 8 9 Queue Full 1(0) 2(1) 3(2) 4(3) 1 is out. 2 is out. 3 is out. 4 is out. Queue Empty Queue Full 1(4) 2(0) 3(1) 4(2)
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
错误代码示范及更正
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 void InitQ (SqQueue &Q,int N) { Q.base=(int *)malloc (N*sizeof (int )); if (Q.base==NULL ){ return ERROR; } Q.front=Q.rear=0 ; return OK; } void AddQ (SqQueue &Q, int x ) { if ((Q.rear+1 )%N==Q.front){ return ERROR; } Q.base[Q.rear]=x; Q.rear=(Q.rear+1 )%N; return OK; } Status DeleteQ (SqQueue &Q,int &e) { if (Q.rear=Q.front){ return ERROR; } e=Q.base[Q.front]; Q.front=(Q.front+1 )%N; return OK; }
第二,观察:
这几行的输出是题目原本代码中没定义的,需要我们加到自己写的函数之中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void InitQ (SqQueue &Q,int N) { Q.base = (Status *)malloc (sizeof (Status)); if (!Q.base) return ; Q.front = Q.rear = 0 ; } void AddQ (SqQueue &Q,int x) { if ((Q.rear+1 )%N == Q.front){ printf ("Queue Full\n" ); return ; } Q.base[Q.rear] = x; Q.rear = (Q.rear+1 )%N; } Status DeleteQ (SqQueue &Q,int &e) { if (Q.front == Q.rear){ printf ("Queue Empty\n" ); return ERROR; } e = Q.base[Q.front]; Q.front = (Q.front+1 )%N; return OK; }
串 知识 单个的字符也可以是子串(长度为1)
重要题目 1 2 3 4 5 6 7 8 9 若串S=“software”,其子串的个数是( B ) A. 8 B. 37 C. 36 D. 9
思路:字符串长度为8,可以有9个空,每两个空之间可以夹出一个子串,所以除空串外有:C(9,2)个子串,最后加上1个空串。
矩阵 重要题目 设有一个 10 阶的对称矩阵 A,采用压缩存储方式,以行序为主存储,a[1, 1] 为第一元素,其存储地址为 1,每个元素占一个地址空间,则 a[8, 5] 的地址为(C )。
A. 13
B. 32
C. 33
D. 40
思路:可以等价于以a[0,0]为第一元素,则a[7,4]的地址。运用公式k = i*(i-1)/2+j-1
,注意a[7,4]是第八行的第五列,所以把i=8与j=5代入即可。
n*(n+1)/2
树 哈夫曼树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 void CreatHuffmanTree (HuffmanTree &HT, int n) { int m, s1, s2, i; if (n <= 1 ) return ; m = 2 * n - 1 ; HT = new HTNode[m + 1 ]; for (i = 1 ; i <= m; ++i) { HT[i].parent = 0 ; HT[i].lchild = 0 ; HT[i].rchild = 0 ; } for (i = 1 ; i <= n; ++i) cin >> HT[i].weight; for (i = n + 1 ; i <= m; ++i) { Select (HT, i - 1 , s1, s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lchild = s1; HT[i].rchild = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; } } void Select (HuffmanTree HT, int len, int &s1, int &s2) { int i, min1 = 32767 , min2 = 32767 ; for (i = 1 ; i <= len; i++) { if (HT[i].weight < min1 && HT[i].parent == 0 ) { s2 = s1; min2 = min1; min1 = HT[i].weight; s1 = i; } else if (HT[i].weight < min2 && HT[i].parent == 0 ) { min2 = HT[i].weight; s2 = i; } } }
排序 直接插入排序 1 2 3 4 5 6 7 8 9 10 11 12 void InsertSort (SqList &L) { int i,j; for (i=2 ;i<=L.length;i++){ if (L.r[i]>L.r[i-1 ]){ L.r[0 ] = L.r[i]; for (j=i-1 ;L.r[j]<L.r[0 ];j--){ L.r[j+1 ] = L.r[j]; } L.r[j+1 ] = L.r[0 ]; } } }