1.Implement exercise 2.3-7.

2. Implement priority queue.

3. Implement Quicksort and answer the following questions. (1) How many comparisons will Quicksort do on a list of n elements that all have the same value? (2) What are the maximum and minimum number of comparisons will Quicksort do on a list of n elements, give an instance for maximum and minimum case respectively.

4. Give a divide and conquer algorithm for the following problem: you are given two sorted lists of size m and n, and are allowed unit time access to the ith element of each list. Give an O(lg m + lgn) time algorithm for computing the kth largest element in the union of the two lists. (For simplicity, you can assume that the elements of the two lists are distinct).

实验过程

1.先读懂题目,由于题目是英文的,所以读懂题目很重要。

2.根据题目回想自己课堂上所学的知识,进行初步思路构思。

3.在本子上写出伪代码,可以简练,自己懂就好。

4.检查伪代码,并上机运行,转换成实际C代码。

5.代码纠错和运行调试,并进行数据测试,数据测试尽可能全面。

具体代码

1.mergesort

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<malloc.h>

#define MAX 10000

void merge_sort(int a[],int p,int r);             //定义函数

int main()

{

for(;;)                                      //无限循环的函数,方便测试

{

int a[10],i;

int j=9;

int x;

srand((int)time(NULL));                //产生随机数

for(i=0;i<10;i++)

{

a[i]=rand()%100;

printf("%d\t",a[i]);

}

printf("请输入给定的和:\n");

scanf("%d",&x);

merge_sort(a,0,9);

i=0;

while(j>i)

{

if(a[i]+a[j]>x)

j--;

else if(a[i]+a[j]<x)

i++;

else

{

printf("a中存在两个数和等于x, 它们分别是%d\t%d\n",a[i],a[j]);

break;

}

}

if(i==j)

printf("a中不存在两个数和等于x\n");

}

system("pause");

return 0;

}

void merge(int a[],int p,int q,int r)

{

int n1,n2;

int i,j,k;

n1=q-p+1;

n2=r-q;

int* L=(int*)malloc(sizeof(int)*(n1+1));

int* R=(int*)malloc(sizeof(int)*(n2+1));

for(i=0;i<n1;i++)

L[i]=a[p+i];

for(j=0;j<n2;j++)

R[j]=a[q+j+1];

L[n1]=MAX;

R[n2]=MAX;

i=0;

j=0;

for(k=p;k<=r;k++)

{

if(L[i]<=R[j])

{

a[k]=L[i];

i++;

}

else

{

a[k]=R[j];

j++;

}

}

free(L);

free(R);

}

void merge_sort(int a[],int p,int r)

{

int q;

if(p<r)

{

q=(p+r)/2;

merge_sort(a,p,q);

merge_sort(a,q+1,r);

merge(a,p,q,r);

}

}

2.priority queue

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<malloc.h>

void build_max_heap(int a[]);

int heap_maximum(int a[]);

int heap_extract_max(int a[]);

void heap_increase_key(int a[],int i,int key);

void max_heap_insert(int a[],int key);

static int heapsize=0;

static int length=0;

int  main()

{

printf("请输入数组的大小:");

scanf("%d",&heapsize);

int m;

int* a=(int *)malloc(sizeof(int)*heapsize);

int i;

srand((int)time(NULL));

for(i=0;i<heapsize;i++)

{

a[i]=rand()%100;

printf("%d\t",a[i]);

}

printf("\n");

build_max_heap(a);

for(i=0;i<heapsize;i++)

{

printf("%d\t",a[i]);

}

printf("\n");

printf("MAXIMUM(S):返回S中具有最大关键字的元素:");

printf("%d\n",heap_maximum(a));

m=heap_maximum(a);

printf("EXTRACT_MAX(S):返回S中具有最大关键字的元素并删除之:");

printf("%d\n",heap_extract_max(a));

printf("MAXIMUM(S):返回新的S中具有最大关键字的元素:");

printf("%d\n",heap_maximum(a));

heapsize++;

a[heapsize-1]=m;

build_max_heap(a);

heap_increase_key(a,1,100);

printf("INCREASE_KEY(S,1,100):将数组下标为1的元素改变为100后的数组:");

for(i=0;i<heapsize;i++)

{

printf("%d\t",a[i]);

}

printf("\n");

max_heap_insert(a,10);

printf("INSORT(S,10):插入元素10后的数组:");

for(i=0;i<heapsize;i++)

{

printf("%d\t",a[i]);

}

printf("\n");

free(a);

system("pause");

return 0;

}

int parent(int i)

{

return (i-1)/2;

}

int left(int i)

{

return 2*i+1;

}

int right(int i)

{

return 2*i+2;

}

void max_heapify(int a[],int i)

{

int l,r,largest;

l=left(i);

r=right(i);

if((l<=heapsize-1)&&a[l]>a[i])

largest=l;

else

largest=i;

if((r<=heapsize-1)&&a[r]>a[largest])

largest=r;

if(largest!=i)

{

int temp=a[i];

a[i]=a[largest];

a[largest]=temp;

max_heapify(a,largest);

}

}

//建立大顶堆过程

void build_max_heap(int a[])

{

length=heapsize;

int i;

for(i=(length-1)/2;i>=0;i--)

max_heapify(a,i);

}

int heap_maximum(int a[])

{

return a[0];

}

int heap_extract_max(int a[])

{

int max;

if(heapsize<1)

{

printf("heap underflow\n");

return -1;

}

else

{

max=a[0];

a[0]=a[heapsize-1];

heapsize=heapsize-1;

max_heapify(a,0);

return max;

}

}

void heap_increase_key(int a[],int i,int key)

{

if(key<a[i]||i>heapsize-1)

printf("new key is smaller than current key\n");

else

{

a[i]=key;

while(i>0&&a[parent(i)]<a[i])

{

int temp=a[i];

a[i]=a[parent(i)];

a[parent(i)]=temp;

i=parent(i);

}

}

}

void max_heap_insert(int a[],int key)

{

heapsize++;

realloc(a,sizeof(int)*heapsize);

a[heapsize-1]=-1;

heap_increase_key(a,heapsize-1,key);

}

3.Quicksort

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

int partition(int a[],int p,int r);

void quicksort(int a[],int p,int r);

void main()

{

int i,a[10];

srand((int)time(NULL));

for(i=0;i<10;i++)

{

a[i]=rand()%100;

printf("%d\t",a[i]);

}

quicksort(a,0,9);

for(i=0;i<10;i++)

{

printf("%d\t",a[i]);

}

}

void quicksort(int a[],int p,int r)

{

int q;

if(p<r)

{

q=partition(a,p,r);

quicksort(a,p,q-1);

quicksort(a,q+1,r);

}

}

int partition(int a[],int p,int r)

{

int x,i,j,temp;

x=a[r];

i=p-1;

for(j=p;j<r;j++)

{

if(a[j]<=x)

{

i++;

temp=a[i];

a[i]=a[j];

a[j]=temp;

}

}

temp=a[i+1];

a[i+1]=a[r];

a[r]=temp;

return i+1;

}

4.divide and conquer

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#include<malloc.h>

int partition(int a[],int p,int r);

void quicksort(int a[],int p,int r);

int findi(int a[],int i);

int FindTheKth(int a[],int b[],int aLeft, int aRight, int bLeft, int bRight, int k) ;

void main()

{

int n,m,i;

srand((int)time(NULL));

printf("请输入两个数组的大小:\n");

printf("n:");

scanf("%d",&n);

printf("m:");

scanf("%d",&m);

int* a=(int*)malloc(sizeof(int)*n);

int* b=(int*)malloc(sizeof(int)*m);

printf("a数组:\n");

for(i=0;i<n;i++)

{

a[i]=rand()%100;

printf("%d\t",a[i]);

}

printf("\nb数组:\n");

for(i=0;i<m;i++)

{

b[i]=rand()%100;

printf("%d\t",b[i]);

}

quicksort(a,0,n-1);

quicksort(b,0,m-1);

printf("\n排序后的a数组:\n");

for(i=0;i<n;i++)

{

printf("%d\t",a[i]);

}

printf("\n排序后的b数组:\n");

for(i=0;i<m;i++)

{

printf("%d\t",b[i]);

}

printf("\n");

printf("数组a的第4个元素:%d\n",findi(a,4));

printf("数组b的第4个元素:%d\n",findi(b,4));

printf("%d\n",FindTheKth(a,b,0, n-1, 0, m-1, 7));

free(a);

free(b);

}

void quicksort(int a[],int p,int r)

{

int q;

if(p<r)

{

q=partition(a,p,r);

quicksort(a,p,q-1);

quicksort(a,q+1,r);

}

}

int partition(int a[],int p,int r)

{

int x,i,j,temp;

x=a[r];

i=p-1;

for(j=p;j<r;j++)

{

if(a[j]<=x)

{

i++;

temp=a[i];

a[i]=a[j];

a[j]=temp;

}

}

temp=a[i+1];

a[i+1]=a[r];

a[r]=temp;

return i+1;

}

int findi(int a[],int i)

{

int size=0;

for(;;)

if(a[size]>=0&&a[size]<=100)

size++;

else

break;

if(i>size||i<1)

{

return -1;

}

else

return a[i-1];

}

int FindTheKth(int a[],int b[],int aLeft, int aRight, int bLeft, int bRight, int k)

{

int aMid = (aLeft + aRight) / 2, bMid = (bLeft + bRight) / 2;

if (aLeft > aRight) return b[bLeft+k-1];

if (bLeft > bRight) return a[aLeft+k-1];

if (a[aMid] <= b[bMid])

{

if (k <= (aMid - aLeft) + (bMid - bLeft) + 1)

{

return FindTheKth(a,b,aLeft, aRight, bLeft, bMid-1, k);

}

else

{

return FindTheKth(a,b,aMid+1, aRight, bLeft, bRight, k-(aMid-aLeft)-1);

}

}

else

{

if (k <= (aMid - aLeft) + (bMid - bLeft) + 1)

{

return FindTheKth(a,b,aLeft, aMid-1, bLeft, bRight, k);

}

else

{

return FindTheKth(a,b,aLeft, aRight, bMid+1, bRight, k-(bMid-bLeft)-1);

}

}

return -1;

}

实验结果

mergesort结果

通过实验我们知道:归并排序是一个典型的分治合并算法,对一个大小的记录序列排序,可以把记录划分成2个记录序列,如果这两个子序列还是不能直接排序,则一真划分,直到序列剩下2个素或者1个元素。分治完毕后再依次两两,直至合并成一个有序表。

如果问题规模为T(n),则分治过程中分成了两个子问题每个子问题的规模是1/2 * T(n/2)
合并排序的运行时间可以分解为:

分解:就是算出中间位置
解决:递归解决两个子问题,时间为1/2 * T(n/2)
合并:我们注意到,在一个含有n个元素的子数组上,Merge过程的运行时间为O(n),由于O(n)是线性关系,不妨设O(n)
= cn;每一层的总规模是cn,一共有logn + 1层,那么复杂度为cn*logn,所以得出O(nlogn)。

priority queue结果

优先队列最基本的功能就是出队时不是按照先进先出的规则,而是按照队列中优先级顺序出队。

1、一般存放实型类型,可比较大小

2、默认情况下底层以Vector实现

3、默认情况下是大顶堆,也就是大者优先级高,后面可以自定义优先级比较规则

堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

堆排序法利用二叉树最大堆实现对数字的排序。其排序的时间为O(nlgn)

divide and conquer结果及分析

原问题是规模为 n 的问题,在树的第一层,把问题分为规模为n/2的两个子问题,如果解决了这两个子问题,把它们合并就能得到原问题的解。现在来看其中的一个子问题,为了解决他们,又把它分为两个规模更小的问题n/4。解决了规模为n/4的问题,合并之就能得到规模 n/2 的问题的解。按照上面的思想,把原问题递归的分解为规模小的问题,然后合并之就能得到原问题的解。

Quicksort结果及分析

本例产生随机数,并将其排序。

快速排序采用的“大事化小,小事化了”的思想,用递归的方法,将原问题分解成若干规模较小但与原问题相似的子问题进行求解。快速算法的平均时间复杂度为O(nlogn) ,平均而言,快速排序是基于关键字比较的内部排序算法中速度最快者;但是由于快速排序采用的是递归的方法,因此当序列的长度比较大时,对系统栈占用会比较多。快速算法尤其适用于随机序列的排序。

实验总结

这次实验总的来说还是蛮顺利的,由于课本上的基础知识提前都看了,而且关于实验的内容提前在课下做了很多,所以还是蛮轻松的,不过,有一点就是,如何将所学习的知识应用于真正的实践中,比如说这次的实验,将伪代码转换称自己的思想是要经消化的,再通过自己的语言表达出来,或者用C,或者C++,或者Java都可以。关于上机,自己也更体会到了算法这门课的奥妙,通过上机,我们才真正怎么将复杂的算法简化,然后减轻计算机的负担,优化程序的执行时间,这在我们以后的编程之中是很有用的。

还有就是课本上的伪代码便于理解,但是如果直接转换成可以运行的代码则又会有一些问题,比如有关数组的下标问题,有关部分循环结构的问题。

总的来说,受益匪浅,辅导老师也解决了我的几个问题。谢谢老师。

算法上机题目mergesort,priority queue,Quicksort,divide and conquer的更多相关文章

  1. 算法学习笔记之——priority queue、heapsort、symbol table、binary search trees

    Priority Queue 类似一个Queue,但是按照priority的大小顺序来出队 一般存在两种方式来实施 排序法(ordered),在元素入队时即进行排序,这样插入操作为O(N),但出队为O ...

  2. 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...

  3. find-median-from-data-stream & multiset priority queue 堆

    https://leetcode.com/problems/find-median-from-data-stream/ 这道题目实在是不错,所以单独拎出来. https://discuss.leetc ...

  4. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅴ

    命题Q.对于一个含有N个元素的基于堆叠优先队列,插入元素操作只需要不超过(lgN + 1)次比较,删除最大元素的操作需要不超过2lgN次比较. 证明.由命题P可知,两种操作都需要在根节点和堆底之间移动 ...

  5. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅳ

    2.4.4 堆的算法 我们用长度为 N + 1的私有数组pq[]来表示一个大小为N的堆,我们不会使用pq[0],堆元素放在pq[1]至pq[N]中.在排序算法中,我们只能通过私有辅助函数less()和 ...

  6. 《Algorithms 4th Edition》读书笔记——2.4 优先队列(priority queue)-Ⅰ

    许多应用程序都需要处理有序的元素,但不一定要求他们全部有序,或者是不一定要以此就将他们排序.很多情况下我们会手机一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素.如此这 ...

  7. 什么是优先级队列(priority queue)?

    有时候我们需要在某个元素集合中找到最小值和最大值 .优先级队列抽象数据(Priority Queue ADT)模型是我们能够使用的方法之一,这是一种支持插入和删除最小值(DeleteMin)或者最大值 ...

  8. STL之heap与优先级队列Priority Queue详解

    一.heap heap并不属于STL容器组件,它分为 max heap 和min heap,在缺省情况下,max-heap是优先队列(priority queue)的底层实现机制.而这个实现机制中的m ...

  9. Priority Queue

    优先队列 集合性质的数据类型离不开插入删除这两操作,主要区别就在于删除的时候删哪个,像栈删最晚插入的,队列删最早插入的,随机队列就随便删,而优先队列删除当前集合里最大(或最小)的元素.优先队列有很多应 ...

随机推荐

  1. 【MySQL】MySQL数据类型

    MySQL表数据存储大小说明 MySQL中规定,任何一条记录(数据表中每行数据)理论上的最大存储容量为 2^16 - 1 (Bytes) = 65535字节. MySQL数据类型思维导图 MySQL数 ...

  2. 小白学 Python(15):基础数据结构(集合)(下)

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  3. CSS(5)---通俗讲解盒子模型

    CSS(5)---盒子模型 盒子模型四个关键字:内容(content).填充(padding).边框(border).边界(margin), CSS盒子模式都具备这些属性. 一.概念 1. 概念 盒子 ...

  4. 【控制系统数字仿真与CAD】实验二:结构图法数字仿真

    一. 实验目的 1. 掌握结构图法仿真复杂控制系统的方法: 2. 掌握复杂系统联接矩阵W和输入联接矩阵W0的求解过程: 3. 掌握复杂系统的环节连接,矩阵A. B. C.D的求解过程: 4. 掌握MA ...

  5. [UWP]使用CompositionAPI的翻转动画

    1. 运行效果 在 使用GetAlphaMask和ContainerVisual制作长阴影(Long Shadow) 这篇文章里我介绍了一个包含长阴影的番茄钟,这个番茄钟在状态切换时用到了翻转动画,效 ...

  6. elastalter邮件告警

    一:简介 ElastAlert是一个简单的框架,用于通过Elasticsearch中的数据异常警告,峰值或其他感兴趣的模式. 监控类型 "匹配Y时间内有X个事件的地方"(frequ ...

  7. nsq (三) 消息传输的可靠性和持久化[二]diskqueue

    上一篇主要说了一下nsq是如何保证消息被消费端成功消费,大概提了一下消息的持久化,--mem-queue-size 设置为 0,所有的消息将会存储到磁盘. 总有人说nsq的持久化问题,消除疑虑的方法就 ...

  8. 小白历险记:spingboot之helloworld

    还记得入职第一天的时候,先安装了相关的软件,配置了环境.boss叫我写的第一个程序:搭建一个springboot工程,输出helloworld. 哈哈话不多说,回忆一下. 1.打开IDEA,点击Cre ...

  9. 012.Kubernetes二进制部署worker节点Flannel

    一 部署flannel 1.1 安装flannel kubernetes 要求集群内各节点(包括 master 节点)能通过 Pod 网段互联互通.flannel 使用 vxlan 技术为各节点创建一 ...

  10. 部署django

    添加uwagi配置文件 在你项目的根目录中创建mysite.xml(名字无所谓),或者创建mysite.ini,输入以下内容: <uwsgi> <socket>127.0.0. ...