经典题型:
第一章:数据结构概述
求算法的时间复杂度:
第二章:线性表
一.单链表
1.初始化
2.创建
3.插入
4.删除
双向链表
1.插入:
s->prior=p; //把p赋值给s的前驱
s->next=p->next;// 把p->next赋值给s的后继
p->next->prior=s;// 把s赋值给p->next的前驱
p->next=s; //把s赋值给p的后继
2.删除:
p->prior->next=p->next; //把p->next赋值给p->prior的后继
p->next->prior=p->prior;//把p->prior赋值给p->next的前驱
free(p); //释放结点
完整单链表基本操作代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode {
int data;
struct LNode* next;
}*LinkNode;
//初始化
void InistLinkNode(LinkNode& L) {
L = (LNode*)malloc(sizeof(LNode));//分配头结点
L->next = NULL;
}
//头插法
void InsertLinkNode(LinkNode& L) {
LNode* s;
int x,Length;
printf("请输入你要插入的元素个数:");
scanf("%d", &Length);
printf("请输入你要插入的元素:\n");
for (int j = 0; j < Length; j++) {
s = (LNode*)malloc(sizeof(LNode));
scanf("%d", &x);
s->data = x;
s->next = L->next;
L->next = s;
}
}
//尾插法
void TailInsertLinkNode(LinkNode& L) {
LNode* s,*r;
int x,Length;
r = L;
printf("请输入你要插入的元素个数:");
scanf("%d", &Length);
printf("请输入你要插入的元素:\n");
for (int j = 0; j < Length; j++) {
s = (LNode*)malloc(sizeof(LNode));
scanf("%d", &x);
s->data = x;
r->next = s;
r = s;
}
printf("\n");
r->next = NULL;
}
//输出单链表
void PrintLinkNode(LinkNode& L)
{
LNode* s=L->next;
printf("单链表元素如下:\n");
while (s != NULL) {
printf("%d", s->data);
s =s->next;
}
printf("\n");
}
//求线性表长度
void lengthLinkNode(LinkNode& L)
{
LNode* s = L->next;
int n=0;
while (s != NULL) {
n++;
s = s->next;
}
printf("单链表长度为:%d",n);
printf("\n");
}
//取第i个元素
void GetElemLinkNode(LinkNode& L) {
printf("请输入你要查找的元素位序:\n");
int i, j = 0;
LNode* s=L;
scanf("%d", &i);
while (j < i && s != NULL) {
j++;
s = s->next;
}
if (s == NULL) {
printf("不存在我们要查找的元素!");
}
else {
printf("元素位序为%d的元素是%d",i, s->data);
}
printf("\n");
}
//删除第i个元素
void DeleteLinkNode(LinkNode& L) {
int x, j = 0,e;
printf("请输入你要删除的元素位序:\n");
scanf("%d", &x);
LNode*p = L;
while (p != NULL && j < x - 1) {
p = p->next;
j++;
}
if (p == NULL)
{
printf("不存在我们要删除的元素!");
}
if (p->next == NULL)
{
printf("不存在我们要删除的元素!");
}
LNode* q = p->next;
e = q->data;
p->next = q->next;
free(q);
}
//在第i个位置插入
void IncreaseLinkNode(LinkNode& L) {
printf("请输入你要插入的元素和位序:(元素和位序之间用逗号隔开)\n");
int x, j = 0, e;
scanf("%d,%d",&e, &x);
LNode* s = L, * r= (LNode*)malloc(sizeof(LNode));
while (j < x-1 && s != NULL) {
j++;
s = s->next;
}
r->data = e;
r->next = s->next;
s->next = r;
}
//查找位序
void SearchLinkNode(LinkNode &L) {
int x,j=1;
LNode* p=L->next;
printf("请输入你要查找的元素:\n");
scanf("%d", &x);
while (p != NULL && p->data != x) {
p = p->next;
j++;
}
if (p == NULL) {
printf("您要查找的元素不存在!");
}
else {
printf("你要查找的元素%d的位序为%d", x, j);
}
}
int main() {
LinkNode L;
InistLinkNode(L);
/*InsertLinkNode(L);*/
TailInsertLinkNode(L);
PrintLinkNode(L);
lengthLinkNode(L);
GetElemLinkNode(L);
IncreaseLinkNode(L);
PrintLinkNode(L);
DeleteLinkNode(L);
PrintLinkNode( L);
SearchLinkNode(L);
}
3.第三章:队和栈
递归:
有一个递归算法,求函数计算次数。
通过画树计算次数。
第四章:串
- 空串是任何字符串的子串(计算字符串个数记得+1个空串)
第五章:数组和广义表
1.数组地址:
- 行优先 行x列下标范围+列
- 列优先 列x行下标范围+行
对角线法:
按行优先 Loc(i, j) = (i * n + j) * p, 按列优先 Loc(i, j) = (j * m + i) * p, 行从下标1 开始 i 就减一, 列从下标 1 开始 , j 就减一
第六章:树
已知先/后序遍历与中序遍历,求后/先序遍历(画图法):
题目结论:
- 结点所拥有的子树的个数称为该节点的度。
- n0=n2+1;
- 叶子节点个数n0,总结点数N关系: n0=上取整(N/2)
- 在一个树T中,边数=节点数-1 ;边数=结点度值*分别对应结点个数;
期末试卷:
一、判断题
1、 线性表的逻辑顺序与存储顺序总是一致的。
2、 顺序存储的线性表可以按序号随机存取。
3、线性表的插入和删除操作不需要付出很大的时间代价,因为每次操作平均只有近一半的元素需要移动。
4、线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有同样的特性,因此是属于同一数据对象。
5、在线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上并不一定紧邻。
6、在线性表的链式存储结构中,逻辑上相邻的两个元素在物理位置上不一定紧邻。
7、线性表的链接存储结构优于顺序存储结构。
8、在线性表的顺序存储结构中,插入和删除时,移动元素的个数与该元素的位置有关。
9、若采用三元组压缩技术存储稀疏矩阵,只要把每个元素的行下标和列下标互换,就完成了对该矩阵的转置运算。
10、线性表的链接存储结构是用一组任意的存储单元来存储线性表中数据元素的。
11、在链表中,要取得某个元素,只要知道指向该元素的指针即可,因此,单链表是随机存取的存储结构。
12、二叉树是树的特殊形式。
13、由树转换成二叉树,其根结点右子树总是空的。
14、先根遍历一颗树和前序遍历与该树对应的二叉树,其结果不同。
15、后根遍历一颗树和中序遍历与该树对应的二叉树,其结果不同。
16、前根遍历森林和前序遍历与该森林对应的二叉树,其结果不同。
17、后根遍历森林和中序遍历与该森林对应的二叉树,其结果不同。
18、不使用递归也可实现二叉树的前序、中序和后序遍历。
19、若一个结点是某二叉树子树的中序遍历序列中的最后一个结点,则它必是该子树的前序遍历序列中的最后一个结点。
20、若一个结点是某二叉树子树的中序遍历序列中的第一个结点,则它必是该子树的后序遍历序列中的第一个结点。
21、不用递归也可实现二叉树的前序、中序和后序遍历。
22、在具有n个结点的二叉树的标准表示形式中,共有n个空指针。
23、满二叉树一定是完全二叉树。
24、在Huffman编码中,出现频率相同的字符编码长度也一定相同。
25、Huffman树是带权路径长度最短的树,路径上权值较大的结点离根最近。
26、由前序序列和后序序列能唯一确定一棵二叉树。
27、由前序序列和中序序列能唯一确定一棵二叉树。
28、由中序序列和后序序列不能唯一确定一棵二叉树。
29、完全二叉树可采用顺序存储结构实现存储,非完全二叉树则不能。
二、选择题*
1、用链表表示线性表的优点是 ( )。
A、便于随机存取 B、花费的存储空间较顺序存储少
C、便于插入和删除 D、数据元素的物理顺序与逻辑顺序相同
2、稀疏矩阵一般的压缩存储方法有两种,即( )。
A、二维数组和三维数组 B、三元组和散列
C、三元组和十字链表 D、散列和十字链表
3、线性表若采用链接存储结构时,要求内存中可用存储单元的地址( )。
A、必须是连续的 B、部分地址必须是连续的
C、一定是不连续的 D、连续不连续都可以
4、串是一种特殊的线性表,其特殊性体现在( )。
A、可以顺序存储 B、数据元素是一个字符
C、可以链接存储 D、数据元素可以是多个字符
5、对顺序存储的线性表,设其长度是n,在任何位置上插入或删除操作都是等概率的。插入一个元素时平均要移动表中的( )个元素。
A、n/2 B、(n+1)/2
C、(n-1)/2 D、n
6、在数据结构中,从逻辑上把数据结构分为( )。
A、动态结构和静态结构 B、紧凑结构和非紧凑结构
C、线性结构和非线性结构 D、内部结构和外部结构
7、设有两个串p和q,求q在p中首次出现的位置的运算称为( )。
A、 连接 B、模式匹配
C、求子串 D、求串长
8、栈结构通常采用的两种存储结构是( )。
A、 顺序存储结构和链表存储结构 B、 散列方式和索引方式
C、 链表存储结构和数组 D、 线性存储结构和非线性存储结构
9、数组通常具有的两个基本操作是( )
A、 建立和删除 B、 索引和修改
C、 查找和修改 D、 查找和索引
10、栈和队列的共同点是 ( )。
A、 都是先进后出 B、 都是先进先出
C、 只允许在端点处插入和删除元素 D、 没有共同点
11、数据结构在计算机内存中的表示是指______
A、数据的存储结构 B、数据结构
C、数据的逻辑结构 D、数据元素之间的关系
12、若一个算法的时间复杂度用T(n)表示,其中n的含义是( )
A、问题规模 B、语句条数
C、循环层数 D、函数数量
13、下列选项中与数据存储结构无关的术语是( )
A、顺序表 B、链表
C、链队列 D、栈
14、已知循环队列的存储空间大小为m,队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置,则向队列中插入新元素时,修改指针的操作是( )
A、rear=(rear-1)%m; B、front=(front+1)%m;
C、front=(front-1)%m; D、rear=(rear+1)%m;
15、栈和队列的共同点是________
A、都是先进后出 B、都是先进先出
C、只允许在端点处插入和删除元素 D、没有共同点
16、已知一堆栈的进栈序列为1234,则下列哪个序列为不可能的出栈序列________
A、1234 B、4321
C、2143 D、4123
17、具有线性结构的数据结构是( )
A、树 B、图
C、栈和队列 D、广义表
18、假设以数组A[60]存放循环队列的元素,其头指针是front=47,当前队列有50个元素,则队列的尾指针值为( )
A、3 B、37
C、50 D、97
19、若栈采用链式存储结构,则下列说法中正确的是( )
A、需要判断栈满且需要判断栈空
B、不需要判断栈满但需要判断栈空
C、需要判断栈满但不需要判断栈空
D、不需要判断栈满也不需要判断栈空
20、若一棵具有n(n>0)个结点的二叉树的先序序列与后序序列正好相反,则该二叉树一定是( )
A、结点均无左孩子的二叉树 B、结点均无右孩子的二叉树
C、高度为n的二叉树 D、存在度为2的结点的二叉树
21、若一棵二叉树中度为l的结点个数是3,度为2的结点个数是4,则该二叉树叶子结点的个数是( )
A、4 B、5
C、7 D、8
22、在n个结点的线索二叉树中,线索的数目为________
A、n-1 B、n
C、n+1 D、2n
23、一棵完全二叉树有1001个结点,其中有_________叶子结点
A、500 B、501
C、503 D、505
24、一个有n个顶点的无向图最多有_______条边。
A、n B、n(n-1)
C、n(n-1)/2 D、2n
四、回答下列问题
错题: