LOADING

加载过慢请开启缓存 浏览器默认开启

2023/12/29

复健!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);

}