41.将一个关键字序列是(7,8,30,11,18,9,14)散列的存储到散列表中,散列表的存储空间是一个从下表0开始的一个一维数组,函数是H(key)=(keyX3)modT .处理冲突采用线性再散列的单侧方法,装载因子是0.7:
1.画出散列表
2.等概率条件下,查找成功和不成功的概率和平均查找长度。
解:
装载因子是当该散列表达到该转载因子 % ,进行再散列。
散列因子 0.7:
数据长度L=T=10
//0.7* 7=4.9=>大于4 开始再散列。
因此可以得到容纳7个数组长度的数组空间必是 (7/0.7)10个:
7 *3 %10=0 –>a[1]
8 *3%10=4 –>a[4]
30 *3%10=0 –>a[0]
11 *3 %10=3 –>a[3]
18 *3 %10=4 –>a[4] 冲突 ->(4+1)%10=5 –》a[5]
9 *3 %10= 7 –>a[7]
14 *3%10=2 –>a[2]
散列表如下:
0 1 2 3 4 5 6 7 8 9
30 7 14 11 8 18 9
2)
成功的概率长度是(平均查找长度)ASL=(1+1+1+1+2+1+1)/7=8/7
不成功ASL即最大可能的查找次数:
因此对应任意一个有效数目: 最坏是到最后依次才查到:
(7+6+5+4+3+2+1)再加上查空 3 次 和冲突1次
=(7+6+5+4+3+2+1)+3+1=32
=》ASL=32/10=3.2
42.(13分)设将n(n>1)个整数存放到一维数组R中,试设计一个在时间和空间两方面尽可能有效的算法,将R中保有的序列循环左移P(0﹤P﹤n)个位置,即将R中的数据由(X0 X1 ……Xn-1)变换为(Xp Xp+1 ……Xn-1 X0 X1 ……Xp-1)要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C或C++或JAVA语言表述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度和空间复杂度
解:
x0 | x1 | ..x2 | x3 | x4 |
《----------------------------------------------------
p=1
x1 | x2 | .x3 | x4 | x0 |
-----------------------------------------------------》
(1)
算法效率-》队列
因此先把P前的元素入队,在把P后的元素依次出队列后插入:
(2)有关代码实现:
.c文件:
#include <stdio.h> #include <stdlib.h> #include "qnode.h" /*是空的队列 * * **/ int isNULL_seq(seqqueue *s) { if (s->front==s->rear) { printf("队列是空的"); return 1; } return 0; } /**满队列 * =》 front++=rear rear 指针用作插入队列 front 指针用作删除队列 * */ int isFull_seq(seqqueue *s) { if ((s->rear+1)%MAXQSIZE==s->front) { printf("队列是满的"); return 1; } return 0; } /**初始化队列: * 初始化队列的元素 * * @key 分配地址,初始化变量 * **/ void init_seqqueue(seqqueue *s) { s->base=(int *)malloc(sizeof(int)*MAXQSIZE); if (!s->base) { printf("分配失败"); exit(-1); } s->front=0; s->rear=0; } /**@key 进入队列:赋值元素 * =》内部状态量控制 * =》 rear指针向左移动->入队 * **/ int in_seqqueue(seqqueue *s, int e) { int temp; if (isFull_seq(s)) { return temp=-1; } s->base[s->rear]=e; s->rear=(s->rear+1)%MAXQSIZE; return temp=1; } /**除队列 * =》base->front * =》fornt 右移动-》出队列 * */ int out_seqqueue(seqqueue *s, int e) { if (isNULL_seq(s)) { return -1; } e=s->base[s->front]; s->front=(s->front+1)%MAXQSIZE; return 1; } /** * cd->update * =》update * =》循环移动N->{n个元素前入队,之后} * */ int circle_left_shift_queue(seqqueue *s, int n) { int i; int e; //对应的起点元素 for (i = 0; i < n; ++i) { //删除在插入 out_seqqueue(s, e); if (i=n) { printf("P节点是%d\n",e); } in_seqqueue(s, e); } return 1; } /** * =》队列结构 * =>输出队列元素 * */ void output_seqqueue(seqqueue *s) { int p; p=s->front; if (p==s->rear) { printf("空的"); } while (p!=s->rear) {//手尾不等 printf("| %d | ", s->base[p]); p=(p+1)%MAXQSIZE; } }![]()
i部分结果是:
(3)时间复杂度O(N);空间复杂度o(p)
证明:设每一次移动的时间 1,
总时间为;Kn 所以O(n)
空间复杂度:借助外部空间时间:供需要P个移动存储时间。