复健!NJUPT数据结构实验报告
摸鱼了太久,该罚
狠狠写两篇数据结构实验报告!
yysy,这两篇报告写下来收获颇丰啊,尤其是C语言的堆与栈存储
实验三
1、参照课本程序2.1~2.7,编写程序,完成顺序表的初始化、查找、插入、删除、输出、撤销等操作。
2、已知带表头结点单链表的类型定义如下:
typedef struct node
{
ElemType element; //结点的数据域
struct node *link; //结点的指针域
}node;
typedef struct
{
struct node * head;
int n;
}headerList;
参照课本程序2.8~2.14,编写程序,完成带表头结点单链表的初始化、查找、插入、删除、输出、撤销等操作。
3、已知带表头结点一元多项式的类型定义如下:
typedef struct pNode
{
int coef;
int exp;
struct pNode* link;
} pNode;
typedef struct
{
struct pNode *head;
} polynominal;
编写程序实现一元多项式的创建、输出、撤销以及两个一元多项式相加和相乘的操作。
实验四
1、已知待排序序列以顺序表结构实现,数据元素以及表结构定义如下:
typedef struct entry //数据元素
{
KeyType key; //排序关键字,KeyType应该为可比较类型
DataType data; //data包含数据元素中的其他数据项
};
typedef struct list{ //顺序表
int n; //待排序数据元素数量
EntryD[MaxSize]; //静态数组存储数据元素
}List;
参照程序10.1~10.7,编写算法,分别实现顺序表的简单选择排序、直接插入排序、冒泡排序、快速排序、两路合并排序以及堆排序。
2、编写算法,利用随机函数,在文件中随机产生n个关键字。(关键字定义为整型数据)
3、编写程序,分别验证在简单选择排序、直接插入排序、冒泡排序、快速排序、两路合并排序以及堆排序,在待排序关键字个数为500、10000、50000、100000时,完成排序所需要的时间。(单位为:毫秒)。
4、将排序结果存放于Excel工作表中,并以图表(簇状柱形图)的方式显示。
#include <stdio.h>
#include <stdlib.h>
// 引入队列便于实现宽度优先遍历
typedef struct {
int* data;
int front;
int rear;
int size;
} Queue;
void createQueue(Queue* q, int maxSize) {
q->data = (int*)malloc(maxSize * sizeof(int));
q->front = 0;
q->rear = -1;
q->size = 0;
}
void destroyQueue(Queue* q) {
free(q->data);
}
int isEmpty(Queue* q) {
return q->size == 0;
}
int isFull(Queue* q) {
return q->size == 100;
}
void enqueue(Queue* q, int item) {
if (isFull(q)) {
printf("Queue is full.\n");
return;
}
q->rear = (q->rear + 1) % 100;
q->data[q->rear] = item;
q->size++;
}
int dequeue(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty.\n");
return -1;
}
int item = q->data[q->front];
q->front = (q->front + 1) % 100;
q->size--;
return item;
}
int front(Queue* q) {
if (isEmpty(q)) {
printf("Queue is empty.\n");
return -1;
}
return q->data[q->front];
}
//1、邻接矩阵的基本操作
typedef struct mGraph{
int **a;
int n; //图的结点数
int e; //图的边数
int noEdge;
}mGraph;
int Init_m(mGraph *mg,int nSize,int noEdgeValue){
int i,j;
mg->n=nSize;
mg->e=0;
mg->noEdge=noEdgeValue;
mg->a=(int**)malloc(nSize*sizeof(int*));
if(!mg->a) return 0;
for(i=0;i<mg->n;i++){
mg->a[i]=(int*)malloc(nSize*sizeof(int));
for(j=0;j<mg->n;j++) mg->a[i][j]=mg->noEdge;
mg->a[i][i]=0;
}
return 1;
}
void Destroy_m(mGraph *mg){
int i;
for(i=0;i<mg->n;i++) free(mg->a[i]);
free(mg->a);
}
int Exist_m(mGraph *mg,int u,int v){
if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v||mg->a[u][v]==mg->noEdge) return 0;
return 1;
}
int Insert_m(mGraph *mg,int u,int v,int w){
if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v) return 0;
if(mg->a[u][v]!=mg->noEdge) return 0;
mg->a[u][v]=w;
mg->e++;
return 1;
}
int Remove_m(mGraph *mg,int u,int v){
if(u<0||v<0||u>mg->n-1||v>mg->n-1||u==v) return 0;
if(mg->a[u][v]==mg->noEdge) return 0;
mg->a[u][v]=mg->noEdge;
mg->e--;
return 1;
}
//2、邻接矩阵的深度优先遍历
void DFS_m(int v,int *visited,mGraph *mg){
visited[v]=1;
printf("%d ",v);
int i;
for(i=0;i<mg->n;i++){
if(mg->a[v][i]!=_I32_MAX&&visited[i]!=1){
DFS_m(i,visited,mg);
}
}
}
void DFS_main_m(mGraph mg){
int *visited=(int *)malloc(mg.n*sizeof(int));
int i;
for(i=0;i<mg.n;i++){
visited[i]=0;
}
for(i=0;i<mg.n;i++){
if(!visited[i]){
DFS_m(i,visited,&mg);
}
}
free(visited);
}
//2、邻接矩阵的宽度优先遍历
void BFS_m(int v,int *visited,mGraph *mg){
Queue q;
createQueue(&q,mg->n);
visited[v]=1;
enqueue(&q,v);
int i;
while(!isEmpty(&q)){
v=front(&q);
visited[v]=1;
printf("%d ",v);
dequeue(&q);
for(i=0;i<mg->n;i++){
if(mg->a[v][i]!=_I32_MAX&&visited[i]!=1){
enqueue(&q,i);
}
}
}
}
//main函数的作用只是遍历调用,防止没有边抵达的结点不被访问
void BFS_main_m(mGraph mg){
int *visited=(int *)malloc(mg.n*sizeof(int));
int i;
for(i=0;i<mg.n;i++){
visited[i]=0;
}
for(i=0;i<mg.n;i++){
if(!visited[i]){
BFS_m(i,visited,&mg);
}
}
free(visited);
}
//1、邻接表的基本操作
typedef struct eNode
{
int adjVex; //与任意顶点u相邻接的顶点
int w; //边的权值
struct eNode *nextArc; //指向下一个边结点
}ENode;
typedef struct lGraph
{
int n; //n为结点数
int e; //e为边数
ENode **a;
}LGraph;
int Init_l (LGraph *lg,int nSize){
int i;
lg->n= nSize;
lg->e=0;
lg->a= (ENode** ) malloc (nSize*sizeof (ENode*)); //动态生成长度为n的一维指针数组
if(!lg->a) return 0;
else{
for(i=0;i<lg->n;i++) lg->a[i]=NULL; //将指针数组a置空
}
return 1;
}
void Destroy_l(LGraph* lg) {
int i;
ENode* p, * q;
for (i = 0; i < lg->n; i++) {
p = lg->a[i];
q = p; //邻接表释放内存要用两个指针,每次释放在后的指针的内存
while (p) {
p = p->nextArc;
free(q);
q = p;
}
}
free(lg->a);
}
int Exist_l(LGraph* lg, int u, int v) { //u为待搜索的母节点,v为要在u邻接结点中搜索的结点
ENode* p;
if (u < 0 || v < 0 || u > lg->n - 1 || v > lg->n - 1 || u == v)
return 0;
p = lg->a[u];
while (p && p->adjVex != v)
p = p->nextArc;
if (!p)
return 0;
else
return 1;
}
int Insert_l(LGraph* lg, int u, int v, int w) {
ENode* p;
if (u < 0 || v < 0 || u > lg->n - 1 || u == v)
return 0;
if (Exist_l(lg, u, v))
return 0;
p = (ENode*)malloc(sizeof(ENode));
if (!p)
return 0;
p->adjVex = v;
p->w = w;
p->nextArc = lg->a[u];
lg->a[u] = p; //后插入的结点在前面
lg->e++;
return 1;
}
int Remove_l(LGraph* lg, int u, int v) {
ENode* p, * q;
if (u < 0 || v < 0 || u > lg->n - 1 || v > lg->n - 1 || u == v)
return 0;
p = lg->a[u];
q = NULL;
while (p && p->adjVex != v) {
q = p;
p = p->nextArc;
}
if (!p)
return 0;
if (q) //如果待删除结点不是表头结点
q->nextArc = p->nextArc;
else
lg->a[u] = p->nextArc; //待删除元素是表头结点,则改变
free(p);
lg->e--;
return 1;
}
//2、邻接表的深度优先遍历
//深度搜索分为两个函数调用,一个函数用来搜索一个结点,主函数则遍历数组,对未被访问的调用DFS
void DFS_l(int v,int *visited,LGraph *lg){
visited[v]=1;
printf("%d ",v); //邻接表表头存储的不是元素值,而是临界元素的地址!!
ENode *p;
for(p=lg->a[v];p;p=p->nextArc){
if(visited[p->adjVex]!=1) DFS_l(p->adjVex,visited,lg);
}
}
void DFS_main_l(LGraph *lg){
int i;
int *visited=(int*)malloc(lg->n*sizeof(int));
for(i=0;i<lg->n;i++){ //不要忘记对visited数组初始化0值
visited[i]=0;
}
for(i=0;i<lg->n;i++){
if(visited[i]!=1){
DFS_l(i,visited,lg);
}
}
free(visited);
}
//2、邻接表的宽度优先遍历
void BFS_l(int v,int* visited,LGraph g){
ENode *w;
Queue q;
createQueue(&q,g.n);
visited[v]=1;
printf("%d ",v);
enqueue(&q,v);
while(!isEmpty(&q)){
v=front(&q);
dequeue(&q);
for(w=g.a[v];w;w=w->nextArc){
if(!visited[w->adjVex]){
visited[w->adjVex]=1;
printf("%d ",w->adjVex);
enqueue(&q,w->adjVex);
}
}
}
}
void BFS_main_l(LGraph g){
int *visited=(int *)malloc(g.n*sizeof(int));
int i;
for(i=0;i<g.n;i++){
visited[i]=0;
}
for(i=0;i<g.n;i++){
if(!visited[i]){
BFS_l(i,visited,g);
}
}
free(visited);
}
//3、迪杰斯特拉算法实现航班最小换乘路线求解
//Choose函数找到 经过上一次最短路线中,新结点邻接路线更新后的 所有路径中最短的,返回的minpos就是接下来确定最短路线的结点
int Choose(int* d,int* s,int n){
int i,minpos;
int min;
min=999999; //用999999代替无穷大,防止溢出
minpos=-1;
for(i=0;i<n;i++){
if(d[i]<min&&!s[i]){
min=d[i];
minpos=i;
}
}
return minpos;
}
int Dijkstra(int v,int* d,int* path,mGraph g){
int i,k,w;
int *s;
if(v<0||v>g.n-1) return 0;
s=(int*)malloc(sizeof(int)*g.n);
for(i=0;i<g.n;i++){ //初始化s数组(源点到i的最短路径是否确定)、d数组(源点到i的最短路径)与path数组
s[i]=0;
d[i]=g.a[v][i];
if(i!=v&&d[i]<999999) path[i]=v;
else path[i]=-1;
}
s[v]=1; d[v]=0;
for(i=1;i<g.n-1;i++){
k=Choose(d,s,g.n);
if(k==-1) continue;
s[k]=1;
printf("%d ",k);
for(w=0;w<g.n;w++){
if(!s[w]&&d[k]+g.a[k][w]<d[w]){
d[w]=d[k]+g.a[k][w];
path[w]=k;
}
}
}
//for(i=0;i<g.n;i++) printf("%d ",d[i]);
return 1;
}
int main(){
int nSize,edgeSize;
printf("输入图结点的个数:\n");
scanf("%d",&nSize);
printf("输入图的边数:\n");
scanf("%d",&edgeSize);
//1、邻接表与邻接矩阵的基本操作
mGraph mg;
Init_m(&mg,nSize,_I32_MAX);
LGraph lg;
Init_l(&lg,nSize);
int i,a,b,w;
printf("以a b w形式输入%d条边,a为起始结点,b为终止结点\n",edgeSize);
for(i=0;i<edgeSize;i++){
scanf("%d %d %d",&a,&b,&w);
if(Insert_l(&lg,a,b,w)!=1||Insert_m(&mg,a,b,w)!=1){ //通过Insert函数构造图
printf("出错");
break;
}
}
//2、邻接表与邻接矩阵的遍历
printf("邻接表深度优先遍历结果:\n");
DFS_main_l(&lg);
printf("\n邻接表宽度优先遍历结果:\n");
BFS_main_l(lg);
printf("\n邻接矩阵深度优先遍历结果:\n");
DFS_main_m(mg);
printf("\n邻接矩阵宽度优先遍历结果:\n");
BFS_main_m(mg);
int u,v;
printf("\n以a b形式输入待删除的边:\n");
scanf("%d %d",&u,&v);
Remove_l(&lg,u,v);
Remove_m(&mg,u,v);
printf("删除边%d-%d后邻接表深度优先遍历的结果:\n",u,v);
DFS_main_l(&lg);
printf("\n删除边%d-%d后邻接矩阵深度优先遍历的结果:\n",u,v);
DFS_main_m(mg);
Destroy_l(&lg);
Destroy_m(&mg);
//3、解决最小换乘次数问题
printf("\n输入航线城市的个数:\n");
scanf("%d",&nSize);
printf("输入航线的边数:\n");
scanf("%d",&edgeSize);
mGraph mg2;
Init_m(&mg2,nSize,999999);
printf("飞机航班:以a b形式输入%d条航线,a为起始结点,b为终止结点\n",edgeSize);
for(i=0;i<edgeSize;i++){
scanf("%d %d",&a,&b);
if(Insert_m(&mg2,a,b,1)!=1){ //飞机航班权重均为1,只要求最少换乘次数即可
printf("出错");
break;
}
}
int *d=(int*)malloc(nSize*sizeof(int));
int *path=(int*)malloc(nSize*sizeof(int));
Dijkstra(0,d,path,mg2);
printf("\n以a b形式输入航线起始城市与终止城市:\n");
scanf("%d %d",&a,&b);
int pnode=b;
printf("最小换乘次数航线为:\n");
while(pnode!=-1){
if(path[pnode]!=-1) printf("%d <-",pnode);
else printf("%d",pnode);
pnode=path[pnode];
}
}
实验四的收获比较大,C语言中,List L;和List* L=(List*)malloc(sizeof(List));两种定义方式是有很大区别的,第一种默认把List结构体存放在栈中,而第二种通过malloc申请的空间则是存放在堆中,栈空间小但读写速度快,堆则刚好相反。
Segmentation fault也是经典老朋友了啊nmd,指针越界、野指针等等问题,现在又遇到个申请空间超过栈上限的错误,累了…
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define KeyType int
#define DataType char
#define MaxSize 100001
typedef struct entry //数据元素
{
KeyType key; //排序关键字,KeyType应该为可比较类型
DataType data; //data包含数据元素中的其他数据项
}Entry;
typedef struct list{ //顺序表
int n; //待排序数据元素数量
Entry D[MaxSize]; //静态数组存储数据元素
}List;
//简单选择排序
int FindMin(List* list,int startIndex){
int i,minIndex=startIndex;
for(i=startIndex+1;i<list->n;i++){
if(list->D[i].key<list->D[minIndex].key)
minIndex=i;
}
return minIndex;
}
void Swap(Entry* D,int i,int j){
Entry temp;
if(i==j) return;
temp=*(D+i);
*(D+i)=*(D+j);
*(D+j)=temp;
}
void SelectSort(List* list){
int minIndex,startIndex=0;
while (startIndex<list->n-1)
{
minIndex=FindMin(list,startIndex);
Swap(list->D,startIndex,minIndex);
startIndex++;
}
}
//直接插入排序
void InsertSort(List* list){
int i,j; //i为待插入元素下标
Entry insertItem;
for(i=1;i<list->n;i++){
insertItem=list->D[i];
for(j=i-1;j>=0;j--){
if(insertItem.key<list->D[j].key)
list->D[j+1]=list->D[j];
else break;
}
list->D[j+1]=insertItem;
}
}
//冒泡排序
void BubbleSort(List*list){
int i,j;
for(i=list->n-1;i>0;i--){
int isSwap= 0;
for(j=0;j<i;j++){
if(list->D[j].key>list->D[j+1].key){
Swap(list->D,j,j+1);
isSwap=1;}
}
if (!isSwap)break;
}
}
int Partition(List*list,int low,int high){
int i=low,j=high+1;
Entry pivot=list->D[low];
do{
do i++;while (i<=high&&list->D[i].key<pivot.key);
do j--;while (j>=low&&list->D[j].key>pivot.key);
if (i<j) Swap(list->D,i,j);
}while (i<j);
Swap(list->D,j,low);
return j;
}
//快速排序
void QuickSort(List*list,int low,int high){
int k;
if(low<high){
k=Partition(list,low,high);
QuickSort(list,low,k-1);
QuickSort(list,k+1,high);
}
}
void quickSort(List*list){
QuickSort(list,0,list->n-1);
}
//两路合并排序
void Merge(List*list,Entry*temp,int low,int n1,int n2){
int i=low,j=low+n1;
while (i<=low +n1-1&&j<=low+n1+n2-1)
{if(list->D[i].key<=list->D[j].key)
*temp++=list->D[i++];
else *temp++=list->D[j++];
}
while (i<=low+n1-1)
*temp++=list->D[i++];
while(j<=low+n1+n2-1)
*temp++=list->D[j++];
}
void MergeSort(List*list){
Entry temp[MaxSize];
int low,n1,n2,i,size=1;while (size<list->n)
{
low=0;while(low+size<list->n){
n1=size;
if(low+size*2<list->n)
n2=size;
else
n2=list->n-low-size;
Merge(list,temp+low,low,n1,n2);
low+=n1+n2;
}
for(i=0;i<low;i++)
list->D[i]=temp[i];
size*=2;
}
}
//堆排序
typedef struct maxheap
{
int n;
Entry D[MaxSize];
}MaxHeap;
void AdjustDown(Entry *D, int i, int n) {
int j = 2 * i + 1; // 左子节点的下标
Entry temp = D[i]; // 保存待调整节点的值
while (j <= n) {
// 选择左右子节点中较大的一个
if (j < n && D[j].key < D[j + 1].key) {
j++;
}
// 如果待调整节点已经大于等于左右子节点中较大的一个,调整结束
if (temp.key >= D[j].key) {
break;
}
// 否则将左右子节点中较大的一个提升到待调整节点的位置,继续向下调整
D[(j - 1) / 2] = D[j];
j = 2 * j + 1;
}
// 将待调整节点放到最终的位置
D[(j - 1) / 2] = temp;
}
void HeapSort(MaxHeap *hp){
int i;
for(i=(hp->n-2)/2;i>=0;i--)
AdjustDown(hp->D,i,hp->n-1);
for(i=hp->n-1;i>0;i--){
Swap(hp->D,0,i);
AdjustDown(hp->D,0,i-1);
}
}
void Sort_Timer_select(List* L,int size){
int i;
L->n=size;
if(size==10000){
FILE *fp;
fp=fopen(".\\data_before_sort.xls","w");
for(i=0;i<size;i++){
L->D[i].key=rand();
fprintf(fp,"%d\n",L->D[i].key);
fflush(fp);
}
fclose(fp);
}
clock_t start,end;
double time_used;
start=clock();
//printf("%lf\n",(double)start);
SelectSort(L);
end=clock();
//printf("%lf\n",(double)end);
time_used=((double)(end-start))/ CLOCKS_PER_SEC;
if(size==10000){
FILE *fp;
fp=fopen(".\\data_after_sort.xls","w");
for(i=0;i<size;i++){
fprintf(fp,"%d\n",L->D[i].key);
fflush(fp);
}
fclose(fp);
}
printf("简单选择排序%d耗时:%lfms\n",size,time_used*1000);
}
void Sort_Timer_insert(List* L,int size){
int i;
L->n=size;
for(i=0;i<size;i++){
L->D[i].key=rand();
}
clock_t start,end;
double time_used;
start=clock();
//printf("%lf\n",(double)start);
InsertSort(L);
end=clock();
//printf("%lf\n",(double)end);
time_used=((double)(end-start))/ CLOCKS_PER_SEC;
printf("直接插入排序%d耗时:%lfms\n",size,time_used*1000);
}
void Sort_Timer_bubble(List* L,int size){
int i;
L->n=size;
for(i=0;i<size;i++){
L->D[i].key=rand();
}
clock_t start,end;
double time_used;
start=clock();
//printf("%lf\n",(double)start);
BubbleSort(L);
end=clock();
//printf("%lf\n",(double)end);
time_used=((double)(end-start))/ CLOCKS_PER_SEC;
printf("冒泡排序%d耗时:%lfms\n",size,time_used*1000);
}
void Sort_Timer_quick(List* L,int size){
int i;
L->n=size;
for(i=0;i<size;i++){
L->D[i].key=rand();
}
clock_t start,end;
double time_used;
start=clock();
//printf("%lf\n",(double)start);
quickSort(L);
end=clock();
//printf("%lf\n",(double)end);
time_used=((double)(end-start))/ CLOCKS_PER_SEC;
printf("快速排序%d耗时:%lfms\n",size,time_used*1000);
}
void Sort_Timer_merge(List* L,int size){
int i;
L->n=size;
for(i=0;i<size;i++){
L->D[i].key=rand();
}
clock_t start,end;
double time_used;
start=clock();
//printf("%lf\n",(double)start);
MergeSort(L);
end=clock();
//printf("%lf\n",(double)end);
time_used=((double)(end-start))/ CLOCKS_PER_SEC;
printf("两路合并排序%d耗时:%lfms\n",size,time_used*1000);
}
void Sort_Timer_heap(MaxHeap* M,int size){
int i;
M->n=size;
for(i=0;i<size;i++){
M->D[i].key=rand();
}
clock_t start,end;
double time_used;
start=clock();
//printf("%lf\n",(double)start);
HeapSort(M);
end=clock();
//printf("%lf\n",(double)end);
time_used=((double)(end-start))/ CLOCKS_PER_SEC;
printf("堆排序%d耗时:%lfms\n",size,time_used*1000);
}
int main(){
int i,size;
printf("输入待排序序列的大小n:\n");
scanf("%d",&size);
List* L=(List*)malloc(sizeof(List)); //使用malloc生成的数组定义在堆上,内存空间很大(G为单位),而如果直接List L;生成的结构体是定义在栈上的,内存空间很有限!(KB单位)
MaxHeap* M=(MaxHeap*)malloc(sizeof(MaxHeap));
L->n=size;
M->n=size;
srand(time(NULL));
for(i=0;i<size;i++){
L->D[i].key=rand();
M->D[i].key=L->D[i].key;
}
printf("随机生成的待排序序列如下:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
SelectSort(L);
printf("对随机序列按升序简单选择排序后:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
InsertSort(L);
printf("对随机序列按升序直接插入排序后:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
BubbleSort(L);
printf("对随机序列按升序冒泡排序后:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
quickSort(L);
printf("对随机序列按升序快速排序后:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
MergeSort(L);
printf("对随机序列按升序两路合并排序后:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
HeapSort(M);
printf("对随机序列按升序堆排序后:\n");
for(int i=0;i<size;i++){
printf("%d ",L->D[i].key);
if(i==size-1) printf("\n");
}
printf("\n");
Sort_Timer_select(L,500);
Sort_Timer_select(L,10000);
Sort_Timer_select(L,50000);
Sort_Timer_select(L,100000);
printf("\n");
Sort_Timer_insert(L,500);
Sort_Timer_insert(L,10000);
Sort_Timer_insert(L,50000);
Sort_Timer_insert(L,100000);
printf("\n");
Sort_Timer_bubble(L,500);
Sort_Timer_bubble(L,10000);
Sort_Timer_bubble(L,50000);
Sort_Timer_bubble(L,100000);
printf("\n");
Sort_Timer_quick(L,500);
Sort_Timer_quick(L,10000);
Sort_Timer_quick(L,50000);
Sort_Timer_quick(L,100000);
printf("\n");
Sort_Timer_merge(L,500);
Sort_Timer_merge(L,10000);
Sort_Timer_merge(L,50000);
Sort_Timer_merge(L,100000);
printf("\n");
Sort_Timer_heap(M,500);
Sort_Timer_heap(M,10000);
Sort_Timer_heap(M,50000);
Sort_Timer_heap(M,100000);
free(L);
free(M);
}