数据结构期末复习题-------算法

  1. 编写一个算法,实现在非递减的有序单链表中插入一个值为x的数据元素,并使单链表仍然保持有序。
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    typedef char datatype;
    typedef struct node
    {
    datatype data;
    struct node *next;
    } linklist;

linklistcreatelist()
{
//int num;
datatype num;/
类型要保持一致 */
linklist *head,s,r;
head=(linklist
)malloc(sizeof(linklist));
r=head;
printf(“请输入非递减链表,以#结束\n”);
fflush(stdin);//清空输入缓冲区,避免回车字符被接收
num=getchar();
while(num!=’#’)
{
s=(linklist
)malloc(sizeof(linklist)); //令s为申请的空间
s->data=num;
r->next=s;
r=s;
fflush(stdin);//清空输入缓冲区,避免回车字符被接收
num=getchar();
}
r->next=NULL;
return head;
}
//在带头节点的单链表head中查找第i个节点,若找到,则返回该节点的存储位置;否则返回NULL

void putout(linklist *head) //单链表的输出
{
linklist *p;
p=head->next;
if(p==NULL) printf(“链表为空”);
else
{
while (p!=NULL)
{
printf("%c",p->data);//先这样写,最后要修改输出之间的间距
p=p->next;
}
}
}

//void insert(linklisthead,int num) //插入函数,x为要插入的结点上的数据
void insert(linklist
head,datatype num/* 类型要保持一致 */) //插入函数,x为要插入的结点上的数据
{
linklist *s,*p,q;
s=(linklist
)malloc(sizeof(linklist)); //令s为申请的空间
s->data=num; //s的数据是num
p=head->next;
q=p->next; //一开始p为第一个结点,q为第二个结点 (样本写反了还是?)
while(q!=NULL)
{
if(num<=q->data&&num>=p->data) //题设要求事先输入的是非递减,
{
p->next=s;
s->next=q;
break;
} //找到并插入
else
{
p=q;
q=q->next;
} //没找到,继续往后移动
}

if(q == NULL)//没找到才执行这里, 不然p->data的值是上面while语句break出来后存的值,再进入这里执行就不对
{
	//if(num>=q->data) //比最大的还大,则插入到最后面s->data能否换成num?
	if(num>=p->data) //这里要写p->data,因为while语句找不到q已经指向NULL了
	{
		//q->next=s;
		p->next=s;//这里要写p->data,因为while语句找不到q已经指向NULL了
		s->next=NULL;

	}
	if(num<=head->next->data)//比最小的还小,则插入到最前面
	{
		p=head->next;  //这一行没看懂有什么意义……待会儿去掉试试
		head->next=s;
		s->next=p;
	}
}

}

void main()
{
linklist head;
//int num;
datatype num;/
类型要保持一致 */
head=createlist();
putout(head);

printf("\n");
printf("请输入一个要插入的元素:");
//scanf("%d",&num);
fflush(stdin);//清空输入缓冲区,避免回车字符被接收
num=getchar();//类型要一致,继续字符形式输入

insert(head,num);//插入
putout(head);//输出

printf("\n");//换行,输出好看一点

}

int Insert_SeqList(SeqList *L, int x)
/把x插入递增有序表L中/
{ if(Làlast+1>=MAXSIZE) return ERROR;
for(i=Làlast; Làelem[i]>x&&i>=0;i–)
Làelem[i+1]=Làelem[i];
Làelem[i+1]=x;
Làlast++;
return OK;
}/*Insert_SeqList */
2.对于给定的一组关键码:503,087,512,061,908,170,897,275, 653,426,分别画出应用直接插入排序、简单选择排序、冒泡排序、冒泡排序以及归并排序对该序列进行排序中各趟的结果序列。
直接插入排序
简单选择排序
冒泡排序

3.已知世界六大城市为:北京(Pe)、纽约(N)、巴黎(Pa)、伦敦(L)、东京(T)、墨西哥(M),表6-1给出了这六大城市之间的交通里程。请完成以下要求:
(1)画出这六大城市的交通网络图;
(2)画出该图的邻接表结构;
(3)画出该图按权值递增的顺序来构造的最小生成树。
表6-1 世界六大城市交通里程
城市 Pe N Pa L T M
Pe 109 82 81 21 124
N 109 58 55 108 32
Pa 82 58 3 97 92
L 81 55 3 95 89
T 21 108 97 95 113
M 124 32 92 89 113

4.已知图的邻接矩阵如下:
V1 V2 V3 V4 V5 V6 V7 V8 V8 V10
V1 0 1 1 1 0 0 0 0 0 0
V2 0 0 0 1 1 0 0 0 0 0
V3 0 0 0 1 0 1 0 0 0 0
V4 0 0 0 0 0 1 1 0 1 0
V5 0 0 0 0 0 0 1 0 0 0
V6 0 0 0 0 0 0 0 1 1 0
V7 0 0 0 0 0 0 0 0 1 0
V8 0 0 0 0 0 0 0 0 0 1
V9 0 0 0 0 0 0 0 0 0 1
V10 0 0 0 0 0 0 0 0 0 0
当用邻接表作为图的存储结构,且邻接表都按序号从大到小排序时,试写出:
• 以顶点V1为出发点的深度优先遍历序列;
• 以顶点V1为出发点的广度优先遍历序列;
• 该图的拓扑有序序列。
5.假设用于通讯的电文仅由8个字母组成,字母在电文中出现的频率分别为0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10 请以字母的频率为权值构造哈夫曼树并为这8个字母设计哈夫曼编码。

A:101

B:001

C:100

D:0001

E:11

F:0000

G:01
带权路径长度WPL=(0.03+0.06)*4+(0.09+0.12+0.17)*3+(0.21+0.32)*2=2.56

6.对长度为15的有序表进行折半查找,请画出折半查找的判定树,并计算等概率查找时平均查找长度ASL。

  1. 设哈希函数H(key)=key%13,用线性探测再散列法处理冲突。试在0~15的散列地址空间中,对关键字序列(19,14,23,01,68,20,84,27,55,11,10,79)构造哈希表,并求等概率情况下查找成功时的平均查找长度。
  2. 以关键码序列{53,87,12,61,98,19,68,75,36,42}为例,手工执行快速排序算法,写出每一趟排序结束时的关键码状态。
  3. 已知图1所示无向网,请给出该网的邻接矩阵;并给出从顶点C1开始,广度优先搜索该图所得的顶点序列和边的序列。
  4. 已知图2所示有向网,试利用Dijkstra算法求顶点1到其余顶点的最短路径,并给出算法执行过程中各步的状态。
  5. 已知关键字序列为:75,33,52,41,12,88,66,27,哈希表长度为10,哈希函数为:H(K)=K%7,解决冲突用线性探测再散列法,请构造相应的哈希表,并求等概率查找该表时的平均查找长度ASL。

ASL=(1+2+1+2+4+1+7+5)/8
12.已知关键字表:(Jan,Feb,Mar,Apr,May,June,July,Aug,Sep,Oct,Nov,Dec)。试按照表中元素的顺序插入一棵初始为空的二叉排序树,画出插入完成后的二叉排序树,并求出等概率查找时查找成功的平均查找长度。

13.有一份电文中共使用了5个字符:a,b,c,d,e,它们的出现频率一次为4、7、5、2、9,试画出对应的哈夫曼树,并求出每个字母的哈夫曼编码。
27
/ \
11 16
/ \ / \
5 6 7 9
/ \
2 4
a、b、c、d、e的哈夫曼编码依次为011、10、00、010、11
14.编写一算法,实现以单链表的第一个元素为基准,将小于该元素的结点全部放到它前面,大于该元素的结点全部放到它后面。要求算法的时间复杂度为O(n),不能申请新空间。
#include<stdio.h>
#include<windows.h>
typedef struct node
{
int value;
struct node *next;
}Node;
int main()
{
struct node *head;
struct node *p,*q,t;
struct node * mySort(struct node head);
int i=0;
p=(struct node
)malloc(sizeof (struct node));
printf(“type-in one number:”);
scanf("%d",&p->value);
p->next=NULL;
head=p;
t=NULL;
for(i=1;i<5;i++)//create list of 5 nodes
{
t=(struct node
)malloc(sizeof (struct node));
printf(“type-in one number:”);
scanf("%d",&t->value);
t->next=NULL;
p->next=t;
p=t;
}
q=head;
printf(“source list:”);
while(q!=NULL)
{
int a=q->value;
printf("%d",q->value);
q=q->next;
}
printf("\n");
p=mySort(head);
printf(“sorted list:”);
while(p!=NULL)
{
printf("%d",p->value);
p=p->next;
}
printf("\n");
system(“pause”);
return 0;
}
struct node * mySort(struct node *head)
{
struct node *shead,*stail;//smaller link
struct node *bhead,*btail;//bigger link
struct node *temp1,*temp3,*temp2;
int temp4;
temp4=head->value;//the first value
temp2=temp1=head;
shead=stail=bhead=btail=NULL;
while(temp1!=NULL)
{
if(temp1head)
temp1=temp1->next;
else
{
temp3=temp1;
temp1=temp1->next;
if(temp3->value<temp4)
{
if(shead
NULL)
{
shead=stail=temp3;
stail->next=NULL;
}
stail->next=temp3;
stail=stail->next;
stail->next=NULL;
}
else
{
if(bheadNULL)
{
bhead=btail=temp3;
btail->next=NULL;
}
btail->next=temp3;
btail=btail->next;
btail->next=NULL;
}
}
}
if(stail
NULL)
{
temp2->next=bhead;
btail->next=NULL;
head=temp2;
}
else
if(btail==NULL)
{
stail->next=temp2;
temp2->next=NULL;
head=shead;
}
else
{
stail->next=temp2;
temp2->next=bhead;
btail->next=NULL;
head=shead;
}
return head;
}
15.要求循环队列不损失一个空间全部都能得到利用,设置一个标志域tag,以tag为0或1来区分头尾指针相同时队列状态的空和满,请编写与此结构相应的入队和出队算法。循环队列的类型定义如下:
#define MAXSIZE 50
typedef struct
{ QueueElementType element[MAXSIZE];
int front, rear, tag;//tag域的值为0表示“空”,1表示“非空"
} SeqQueue;
#include<stdio.h>
#include<malloc.h>
#include<string.h>

#define MAXSIZE 50
typedef struct
{
int elem[MAXSIZE];
int front;
int rear;
int tag;
}SeqQueue;

void Init(SeqQueue *Q)
{
Q->front = Q->rear =0;
Q->tag =0;
}

void Enter(SeqQueue *Q,int n,int x)
{
if(Q->rear == Q->front && Q->tag ==1)
printf(“The queue is full\n”);
else{
Q->elem[Q->rear] = x;
Q->rear = (Q->rear+1)%n;
printf(“Succes\n”);
if(Q->rear == Q->front)
Q->tag=1;
}
}

void Del(SeqQueue *Q,int n)
{
if(Q->front == Q->rear && Q->tag == 0)
printf(“The queue is empty\n”);
else
{
printf("%d\n",Q->elem[Q->front]);
Q->front =(Q->front+1)%n;
if(Q->front == Q->rear)
Q->tag =0;
}
}
int main()
{
int n,m,i,x;
char str[5];
SeqQueue Q;
while(scanf("%d%d",&n,&m)!=EOF){
Init(&Q);
for(i=0;i<m;i++)
{
scanf("%s",str);
if(strcmp(str,“IN”) == 0)
{
scanf("%d",&x);
Enter(&Q,n,x);
}
else
Del(&Q,n);
}
}
return 0;

}

# define MAXSIZE 50
typedef struct
{ QueueElementType element[MAXSIZE];
int front, rear,tag;
} SeqQueue;
int EnterQueue(SeqQueue *Q,int x)
{if(Qàtag1&&Q–>frontQ–>rear)
return FALSE;//tag域的值为1表示“非空”
Qàelement[Qàrear]=x;
Qàrear=(Q à rear+1)%MAXSIZE;
if(Q à tag0) Q à tag=1; //队列不空
return TRUE;
}//EnterQueue
int DeleteQueue(SeqQueue *Q, int *x)
{if(Q–>tag
0) return FALSE;

  • x=Q–>element [Q–>front];
    Q–>front=(Q–>front+1)%MAXSIZE;
    if(Q–>front==Q–>rear) Q–>tag=0; //队列空
    return TRUE;
    }//DeleteQueue
    16.一已知二叉树采用二叉链表存放,要求返回二叉树的后序遍历序列中的第一个结点的指针,是否可以不用递归且不用栈来完成?请简述原因。
    答:可以,后序遍历的顺序是左右根,所以二叉树最左下的叶子结点是第一个遍历结点。
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值