软件技术(数据结构)所有主要程序-本人手写,均调试运行通过

本文介绍了数据结构中的关键程序,包括顺序表操作、栈及队列的实现,并提供了详细的源代码示例。深入探讨了初始化顺序表、栈与队列的基本操作及遍历二叉树等算法。

软件技术(数据结构)所有主要程序-本人手写,均调试运行通过

数据结构主要程序:

  1. 程序文件名为table.cpp,源程序清单如下:

/*******************************Copyright (c)*********************************************

**                University of Electronic Science and Technology of China

**                  School of Communication and Information Engineering

**                          http://www.uestc.edu.cn

**

**--------------------------- File Info ---------------------------------------------------

** File name:           table.cpp

** Last modified Date:  2012-12-19

** Last Version:        1.0

** Descriptions:        各种顺序表操作,顺序表结构的定义在mystruct.h中,

**                      函数中使用的与界面显示有关接口的说明在ui.h

**                      本文件基于C语言风格

**------------------------------------------------------------------------------------------

** Created by:          Duan Jingshan

** Created date:        2012-12-19

**------------------------------------------------------------------------------------------

** Modified by:  

** Modified date:

** Version:   

** Descriptions: 

**

*******************************************************************************************/

#include "stdafx.h"

#include "mystruct.h"

#include "ui.h"

#include<stdlib.h>

/*******************************************************************************************

** Function name: init_table()

** Descriptions    :    初始化顺序表

**                  顺序表利用数组作为基础,其特点是需要事先获得全部元素空间,因此本函数的主要

**                  功能就是向系统申请足够的空间作为顺序表的存储空间。涉及的系统函数为:

**                  malloc()

**                  此外,良好的习惯是将空间内的各项数据进行适当的初始化

** Input: NONE

** Output:  NONE

**   return:  类型:table_t *,返回顺序表的结构指针

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

table_t * init_table()

{

    table_t *t= (table_t *)malloc(sizeof(table_t));

     t->length=0;

     if (t!=0)

         return t;

     else

         return NULL;

}

/*******************************************************************************************

** Function name: free_table()

** Descriptions    :    释放顺序表空间

**                  当程序结束时会通过本函数来释放通过malloc获得的顺序表空间

** Input: table_t * t; 顺序表指针

** Output:  NONE

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void free_table(table_t * t)

{

     free(t);

}

/*******************************************************************************************

** Function name: get_table()

** Descriptions    :    查询顺序表

**                  查询顺序表中第i个元素

** Input:

**        table_t * table; 顺序表指针

**        int index;  查询位置,即第i个元素

** Output: 

**        element_t * elem; 元素域指针,用来存放被查询到的元素内容,

**                      (注意,需要将元素全部内容拷贝到该指针所记录的空间中,即,使用memcpy())

**   return:  类型:int,返回查询是否成功,为0表示找到指定元素,为-1表示没有找到,一般是因为

**                       index指示的位置超出了顺序表的范围

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int get_table(table_t * table,int index, element_t * elem)

{

     //判断index是否超出顺序表范围

     if(index <= 0 || index > table->length){

         return -1;

     }

     //复制元素内容到指定空间中;

     memcpy(elem,&(table->data[index-1]),sizeof(element_t));//error

     return 0;

}

/*******************************************************************************************

** Function name: add_table()

** Descriptions    :    将指定元素放入到顺序表的末尾

** Input:

**        table_t * table; 顺序表指针

**        element_t data; 待放入的元素

** Output:

**        table_t * table; 添加新元素后的顺序表指针

**   return:  类型:int; 为-1表示放入失败,一般是因为顺序表已经放满,为0表示正确放入

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int add_table(table_t * table, element_t data)

{

     if (table->length==MAX_TABLE_SIZE)

     return -1;

     else

     {

         table->data[table->length]=data;

         table->length++;

         return 0;

     }

}

/*******************************************************************************************

** Function name: insert_table()

** Descriptions    :    将指定元素插入到顺序表的指定位置之前

** Input:

**        table_t * table; 顺序表指针

**        element_t data; 待放入的元素

**        int location;  插入位置,语义是:第X个元素前,,当location大于链表元素总数时,该元素

**                       将插入到表尾。

** Output:

**        table_t * table; 插入新元素后的顺序表指针

**   return:  类型:int; 为-1表示插入失败,一般是因为顺序表已经放满或者插入位置不正确,

                         为0表示正确插入

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int insert_table(table_t * table, element_t data, int location)

{

     int j=0;

     if (table->length>=MAX_TABLE_SIZE)

     return -1;

     else

     {

         if (location<=0)

         return -1;

         else if(location>table->length)

         {

         table->length++;

         table->data[table->length-1]=data;  

         }

         else

         {

              for(j=table->length-1;j>=location-1;j--)

              {

                   table->data[j+1]=table->data[j];

              }

              table->data[location-1]=data;

              table->length++;

         }

     }

     return 0;

}

/*******************************************************************************************

** Function name: insert_table_by_order()

** Descriptions    :    将指定元素按照学号从小到大顺序插入到顺序表中

** Input:

**        table_t * table; 顺序表指针

**        element_t data; 待放入的元素

** Output:

**        table_t * table; 插入新元素后的顺序表指针

**   return:  类型:int; 为-1表示插入失败,一般是因为顺序表已经放满或者插入位置不正确,

                         为0表示正确插入

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int insert_table_by_order(table_t * table, element_t data)

{

     int i=0,j=0,flag=0;

     element_t t;

     for(i=0;i<table->length;i++)

     {

         for(j=i;j<table->length-1;j++)

         {

              if(table->data[j].stuID>table->data[j+1].stuID)

              {

                   t=table->data[j];

                   table->data[j]=table->data[j+1];

                   table->data[j+1]=t;

              }

         }

     }

     if (table->length>=MAX_TABLE_SIZE)

     return -1;

     else

     {

     for (i=0;i<table->length;i++)

     {

         if (data.stuID<table->data[i].stuID)

         {

              flag=i;

              break;

         }

     }

     for (j=table->length-1;j>=flag;j--)

     {

         table->data[j+1]=table->data[j];

     }

     table->data[flag]=data;

     table->length++;

     }

     return 0;

}

/*******************************************************************************************

** Function name: delete_table()

** Descriptions    :    删除顺序表中指定姓名作为关键字的元素

** Input:

**        table_t * table; 顺序表指针

**        char * name; 以该姓名为关键字的元素将被删除

** Output:

**        table_t * table; 删除指定元素后的顺序表指针  

**   return:  类型:int; 为-1表示删除失败,一般是因为顺序表没有找到指定元素,

                         为0表示正确删除

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int delete_table(table_t * table, char * name)

{

     int i=0,j=0;

     int flag=table->length;

     for(i=0;i<table->length;i++)

     {

     if(strcmp(table->data[i].stuName,name)==0)

         {

         for(j=i+1;j<table->length;j++)

         {

              table->data[j-1]=table->data[j];

         }

              table->length--;

              break;

         }

     }

     if(table->length==flag)

         return -1;

     else

         return 0;

}

/*******************************************************************************************

** Function name: delete_table_below()

** Descriptions    :    删除顺序表中总分小于某个指定值的所有元素,本算法的特点是

**                  希望一趟能在顺序表中删除多个元素

** Input:

**        table_t * table; 顺序表指针

**        int x; 删除范围,即被删除的元素总分小于这个值

** Output:

**        table_t * table; 删除元素后的顺序表指针 

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void delete_table_below(table_t * table, int x)

{

     int i=0,j=0;

     for(i=0;i<table->length;i++)

     {

         if(table->data[i].overall>=x)

         {

              table->data[j]=table->data[i];

              j++;

         }

     }

     table->length=j;

}

A、拓展训练ex1_2(1) 顺序表插入操作

  1. 程序流程说明:

初始化顺序表

——>

自定义顺序表元素

——>

顺序表元素排序(冒泡排序法)

——>

按从小到大的顺序插入元素

——>

输出顺序表

  1. 程序文件名为ex1_1(顺序表插入),源程序清单如下:

//by郑元帅 2016010901012 通信与信息工程学院  指导教师:居太亮

#include<stdio.h>

struct Listt

{

     int num;

     int data[100];

}listt;

//模块化,子函数化

//初始化 自定义向量,包含向量长度(<0,=0,>0)判断报错

//返回值1或0,决定程序运行结束与否

//包含增序排序函数,冒泡排序法 ,可独立成子函数

int init(Listt *list)

 {

     int t=0;

     int i=0,j=0;

     printf("请输入向量的长度(>=0的自然数):");

     scanf("%d",&list->num);

     if (list->num<0)

     {

         return 0;

      }

     else if(listt.num==0)

     {

         list->data[0]=NULL;

         return 1;

     }

     else

     {

     printf("请输入自定义向量元素(数字):\n");

     for (i=0;i<list->num;i++)

         {

              scanf("%d",&list->data[i]);

         }

     for (j=0;j<list->num-1;j++)

         for (i=0;i<list->num-j-1;i++)

              {

                   if (list->data[i]>list->data[i+1])

                   {

                   t=list->data[i];

                   list->data[i]=list->data[i+1];

                   list->data[i+1]=t;

                   }

              }

     printf("递增排序后的向量组:\n");

     for (i=0;i<list->num;i++)

         {

              printf("%d\t",list->data[i]);

         }

     printf("\n");

     return 1;

     }

 }

// 插入函数,包含向量长度(=0,>0)判断,插入元素(数字)大小判断与位置标记flag

//flag位置及之后向量元素后移一个单位 ,然后插入元素x,向量长度+1

void insertlist(Listt *l,int x)

 {

     int j=0,i=0;

     int flag=0;

     if(l->num==0)

     {

         l->data[0]=x;

     }

     for (i=0;i<l->num;i++)

     {

         if (x<l->data[i])

         {

              flag=i;

              break;

         }

     }

     if (x>l->data[0]&flag==0)

     {

         l->num++;

         l->data[l->num-1]=x;

     }

     else

     {

     for (j=l->num-1;j>=flag;j--)

     {

         l->data[j+1]=l->data[j];

     }

     l->data[flag]=x;

     l->num++;

    }

 }

// 输出函数

 void print_f(Listt *pl)

 {

     int i;

     for (i=0;i<pl->num;i++)

         {

         printf("%d\t",pl->data[i]);

         }

 }

//主函数,包含错误判断 ,调用子函数

int main()

{

     int x=0;

     if (init(&listt)==0)

     {

         printf("自定义向量长度错误!结束。");

         return 0;

     }

     else

     {

     printf("\n请输入插入元素(数字):");

     scanf("%d",&x);

     insertlist(&listt,x);

     printf("插入元素后的向量:\n");

     print_f(&listt);

     }

 }

B、拓展训练ex1_2(2) 顺序表删除负数

  1. 程序流程说明:

初始化顺序表

——>

自定义顺序表元素

——>

删除负数(依次将保留项向前覆盖)

——>

输出顺序表

——>

退出程序

  1. 程序文件名为ex1_2(2)删除负数,源程序清单如下:

//by郑元帅 2016010901012 通信与信息工程学院  指导教师:居太亮

#include<stdio.h>

#include<stdlib.h>

struct Listt

{

     int num;

     int data[100];

}listt;

//模块化,子函数化

//初始化 自定义向量

void init(Listt *list)

 {

     list->num=0;

 }

//输入函数 ,自定义顺序表

void input_f(Listt *p)

{

     int i=0;

     printf("请输入顺序表中元素个数:");

     scanf("%d",&p->num);

     printf("请依次输入顺序表中的元素:\n");

     for (i=0;i<p->num;i++)

     {

         scanf("%d",&p->data[i]);

      }

}

// 输出函数

 void print_f(Listt *pl)

 {

     int i;

     for (i=0;i<pl->num;i++)

         {

         printf("%d\t",pl->data[i]);

         }

 }

 //删除负数

 void delete_negative(Listt *p)

 {

     int i=0,j=0;

     for(i=0;i<p->num;i++)

     {

         if(p->data[i]>=0)

         {

              p->data[j]=p->data[i];

              j++;

         }

     }

     p->num=j;

  }

//主函数,包含错误判断 ,调用子函数

int main()

{

     int x=0;

    init(&listt);

    input_f(&listt);

    delete_negative(&listt);

    if (listt.num==0)

    {

    printf("顺序表为空。");

    return 0;

    }

    else

    {

     print_f(&listt);

     return 0;

     }

}

C、拓展训练ex1_2(3) 顺序表原表反序

  1. 程序流程说明:

初始化顺序表

——>

自定义顺序表元素

——>

选定旋转轴

——>

原表上反序操作

——>

输出顺序表

——>

程序退出

  1. 程序文件名为ex1_2(2)删除负数,源程序清单如下:

#include"stdio.h"

#define M 100

struct list

{

     int data[M];

     int length;

}ls;

//初始化顺序表,自定义顺序表元素

int init(list *l)

{

     int x=0,i=0;

     l->length=0;

     printf("请输入顺序表元素个数:");

     scanf("%d",&l->length);

     if(l->length<=0)

     {

         return 0;

     }

     printf("请输入顺序表元素:\n");

     for(i=0;i<l->length;i++)

     {

         scanf("%d",&x);

         l->data[i]=x;

     }

     printf("您输入的顺序表为:\n");

     for(i=0;i<l->length;i++)

     {

         printf("%d\t",l->data[i]);

     }

}

//原表上反序操作

void reverse(list *l)

{

     int i=0,k=0,t=0;

     k=(int)(l->length/2);

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

     {

         t=l->data[i];

         l->data[i]=l->data[l->length-1-i] ;

         l->data[l->length-1-i]=t;

     }

}

//输出函数

int printf_ls(list *l)

{

     int i=0;

     printf("\n倒序后的顺序表为:\n");

     for(i=0;i<l->length;i++)

     {

         printf("%d\t",l->data[i]);      

     }

}

//主函数,判断初始化错误,调用子函数

int main()

{

     if(init(&ls)==0)

     {

     printf("输入错误,顺序表为空或无定义,已退出");

     return 0;

     }

     reverse(&ls);

     printf_ls(&ls);

     return 0;

}

  1. 程序流程说明:

初始化链表,只需要为链表申请少量结构所需的空间即可。

——>

将指定元素放入到链表的末尾。

——>

查询链表中的第i个元素。

——>

将指定元素插入到链表的指定位置之前。

——>

将指定元素按照学号从小到大顺序插入到链表中(先冒泡排序,再插入)

——>

删除链表中指定姓名作为关键字的元素

——>

删除链表中总分小于某个指定值的所有元素(一趟在链表中删除多个元素)

——>

释放存储空间,结束程序

 

  1. 程序文件名为link.cpp,源程序清单如下:

 /*******************************Copyright (c)*********************************************

**                University of Electronic Science and Technology of China

**                  School of Communication and Information Engineering

**                          http://www.uestc.edu.cn

**

**--------------------------- File Info ---------------------------------------------------

** File name:           link.cpp

** Last modified Date:  2012-12-19

** Last Version:        1.0

** Descriptions:        各种链表操作,链表结构的定义在mystruct.h中,

**                      函数中使用的与界面显示有关接口的说明在ui.h

**                      本文件基于C语言风格

**------------------------------------------------------------------------------------------

** Created by:          Duan Jingshan

** Created date:        2012-12-19

**------------------------------------------------------------------------------------------

** Modified by:  

** Modified date:

** Version:   

** Descriptions: 

**

*******************************************************************************************/

#include "stdafx.h"

#include "mystruct.h"

#include "ui.h"

#include<stdio.h>

#include<stdlib.h>

/*******************************************************************************************

** Function name: init_link()

** Descriptions    :    初始化链表

**                  链表的特点是利用内存离散空间存放各个元素,因此不必事先为链表准备足够大

**                  的内存空间,只是在需要插入新元素时,才申请必要的链点空间。因此在初始化

**                  链表时,只需要为链表申请少量结构所需的空间即可。

**                  关键是要将其中的头指针设置为空

** Input: NONE

** Output:  NONE

**   return:  类型:link_t *,返回链表的结构指针

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

link_t * init_link()

{

     link_t *li; 

     li= (link_t *)malloc(sizeof(link_t));

    li->head = NULL;

     li->length=0;

    return li;

}

/*******************************************************************************************

** Function name: free_link()

** Descriptions    :    释放链表空间

**                  当程序结束时会通过本函数来释放链表空间,如果链表中还有元素,则需要逐个将

**                  元素的空间予以释放

** Input: link_t * t; 链表结构指针

** Output:  NONE

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void free_link(link_t * t)

{

     node_t * p;

     if(t == NULL){

         return;

     }

     //如果链表中有链点,则需要逐个释放各链点空间,不能只是free(t);

     t->head=p;

     while(t->head != NULL){

         p = t->head;

         t->head = t->head->next;

         free(p);

     }

     t->head = NULL;

     t->length = 0;

     free(t);

}

/*******************************************************************************************

** Function name: add_link()

** Descriptions    :    将指定元素放入到链表的末尾

** Input:

**        link_t * link; 链表结构指针

**        element_t data; 待放入的元素

** Output:

**        link_t * link; 添加新元素后的链表指针

**   return:  类型:int; 为-1表示放入失败,一般是因为申请不到链点空间,为0表示正确放入

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int add_link(link_t * link, element_t data)

{

     node_t *p,*t; 

     p = (node_t *)malloc(sizeof(node_t));   //申请新的结点

     t = (node_t *)malloc(sizeof(node_t));

     if (p==NULL||t==NULL)

         return -1;

     else if(link->head==NULL)

     {

         link->head=t;

         t->data=data;

         t->next=NULL;

         link->length++;

         return 0;

     }

     else

     {

     p=link->head;

     while(p->next!=NULL)

         p=p->next;

     p->next=t;

     t->data = data;                     //结点数据域赋值

     t->next=NULL;

     link->length++;

     return 0;

     }

}

/*******************************************************************************************

** Function name: get_link()

** Descriptions    :    查询链表

**                  查询链表中第i个元素

** Input:

**        link_t * link; 顺序表指针

**        int index;  查询位置,即第i个元素

** Output: 

**        element_t * elem; 元素域指针,用来存放被查询到的元素内容,

**                      (注意,需要将元素全部内容拷贝到该指针所记录的空间中,即,使用memcpy())

**   return:  类型:int,返回查询是否成功,为0表示找到指定元素,为-1表示没有找到,一般是因为

**                       index指示的位置超出了顺序表的范围

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int get_link(link_t * link,int index, element_t * elem)

{

     node_t *p;

     int j=1;

     p=link->head;

     if(index <= 0 || index > link->length){

         return -1;

     }   

     while(p->next!=NULL&&j<index)

     {

         p=p->next;

         j++;

     }   

     if (p!=NULL&&j==index)

         memcpy(elem,&(p->data),sizeof(element_t));    

     return 0;

}

/*******************************************************************************************

** Function name: insert_link()

** Descriptions    :    将指定元素插入到链表的指定位置之前

** Input:

**        link_t * link; 链表结构指针

**        element_t data; 待放入的元素

**        int location;  插入位置,语义是:第X个元素前,当location大于链表元素总数时,该元素

**                       将插入到表尾。

** Output:

**        link_t * link; 插入新元素后的链表结构指针

**   return:  类型:int; 为-1表示插入失败,一般是因为没有申请到空间而无法生成链点

                         为0表示正确插入

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int insert_link(link_t * link, element_t data, int location)

{

     node_t *p,*t;

     t=(node_t *)malloc(2*sizeof(node_t));

     p=(node_t *)malloc(sizeof(node_t));

     int j=1;

     p=link->head;

     while(p!=NULL&&j<location-1)

     {

         p=p->next;

         j++;

     }

     if(j!=location-1)

     {

         return -1;

     }

     else

     {

     t->data=data;

     t->next=p->next;

     p->next=t;

     link->length++;

     return 0;

     }

}

/*******************************************************************************************

** Function name: insert_link_by_order()

** Descriptions    :    将指定元素按照学号从小到大顺序插入到链表中

** Input:

**        link_t * link; 链表指针

**        element_t data; 待放入的元素

** Output:

**        link_t * link; 插入新元素后的链表指针   

**   return:  类型:int; 为-1表示插入失败,一般是因为没有申请到空间而无法生成链点,

                         为0表示正确插入

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int insert_link_by_order(link_t * link, element_t data)

{

     int i=0,j=0;

     node_t *p,*s,*t;

     t=(node_t *)malloc(sizeof(node_t));

     p=(node_t *)malloc(sizeof(node_t));

     s=(node_t *)malloc(sizeof(node_t));

     element_t temp;

     for(i=1;i<link->length-1;i++)

     {

         p=link->head;

         for(j=0;j<link->length-i;j++)

         {

              if(p->data.stuID>p->next->data.stuID)

              {

                   temp=p->data;

                   p->data=p->next->data;

                   p->next->data=temp;

              }

              p=p->next;

         }

     }

     p=link->head;

     if(data.stuID<=link->head->data.stuID)

     {

         t->data=data;

         t->next=link->head->next;

         link->head=t;

         link->length++;

         return 0;

     }

     else

     {

         p=link->head;

     while(p->next!=NULL)

     {

         if(data.stuID<=p->next->data.stuID)

         {

         //   s=p->next;

              t->data=data;

         //   p->next=t;

         //   t->next=s;

              t->next=p->next;

              p->next=t;

              link->length++;

              return 0;

         }

         p=p->next;

     }

     }

}

/*******************************************************************************************

** Function name: delete_link()

** Descriptions    :    删除链表中指定姓名作为关键字的元素

** Input:

**        link_t * link; 链表指针

**        char * name; 以该姓名为关键字的元素将被删除,其链点空间也需要被释放

** Output:

**        link_t * link; 删除指定元素后的链表指针 

**   return:  类型:int; 为-1表示删除失败,一般是因为在链表中没有找到指定元素,

                         为0表示正确删除

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int delete_link(link_t * link, char * name)

{

     node_t *p,*s;

     int j=0,i=0;

     p=link->head;

     while(strcmp(p->data.stuName,name)!=0)

     {

         p=p->next;

         j++;

     }

     p=link->head;

     while(p->next!=NULL&&i<j-1)

     {

         p=p->next;

         i++;

     }

     if(p->next==NULL)

         return -1;

     s=p->next;

     p->next=s->next;

     free(s);

     link->length--;

     return 0;

}

/*******************************************************************************************

** Function name: delete_link_below()

** Descriptions    :    删除链表中总分小于某个指定值的所有元素,本算法的特点是

**                  希望一趟能在链表中删除多个元素

** Input:

**        link_t * link; 链表指针

**        int x; 删除范围,即被删除的元素总分小于这个值

** Output:

**        link_t * link; 删除元素后的链表结构指针 

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void delete_link_below(link_t * link, int x)

{

     node_t *p,*t,*s;  

     while(link->head->data.overall<x)

     {

     t=link->head->next;

     link->head=t;

     link->length--;

     }

     p=link->head;

     while(p->next!=NULL)

     {

         s=p->next;

         if(s->data.overall<x)

         {

              p->next=s->next;

              link->length--;

         }

         else

         {

              p=p->next;

         }

     }

}

ex2_2——扩展题

   1)创建一个单链表,其数据元素为整数,从键盘输入,输入0结束(注意0不放到链表内);

   2)从键盘任意输入一个整数,在单链表中查询该数,如果单链表中已经存在这个数,就调用删除函数,删除该元素所在结点,并将单链表在删除前后的数据元素依次输出到屏幕上;

   如果单链表中不存在这个数,就调用插入函数,将这个数插入到单链表尾,并将单链表在插入前后的数据元素依次输出到屏幕上。

3)教材第一章习题第9题(用链表实现)

ex2_3——扩展题

1)删除单链表中全部的负数

2)创建一个双向链表,按照冒泡排序的思路对这个双向链表进行排序,打印排序结果。注意,本算法在交换元素时是将链点整个交换而不是将链点中的元素值交换。

程序一: ex2_2_12——扩展题

   1)创建一个单链表,其数据元素为整数,从键盘输入,输入0结束(注意0不放到链表内);

   2)从键盘任意输入一个整数,在单链表中查询该数,如果单链表中已经存在这个数,就调用删除函数,删除该元素所在结点,并将单链表在删除前后的数据元素依次输出到屏幕上;

   如果单链表中不存在这个数,就调用插入函数,将这个数插入到单链表尾,并将单链表在插入前后的数据元素依次输出到屏幕上。

程序二:用链表实现有序向量按序插入元素。(教材第九题)

程序三:删除单链表中的所有负数。

程序四:创建一个双向链表,按照冒泡排序的思路对这个双向链表进行排序,打印排序结果。注意,本算法在交换元素时是将链点整个交换而不是将链点中的元素值交换。

程序四:ex2_3_2流程说明:

  1. 源程序清单如下:

程序文件名为ex2_2_12.cpp,源程序:

 #include<stdio.h>

#include<stdlib.h>

//by 郑元帅 2016010901012 软件技术基础实验 UESTC 

//定义节点结构,定义链表结构

typedef struct node_t{

     int data;

     struct node_t* next;

}node_t;

typedef struct link_t{

     node_t * head;

     int length;

}link_t;

//创建链表函数

int add_link(link_t * link, int data)

{

     node_t *p,*t; 

     //申请新的结点

     p = (node_t *)malloc(sizeof(node_t)); 

     t = (node_t *)malloc(sizeof(node_t));

     if (p==NULL||t==NULL)

         return -1;

     else if(link->head==NULL)

     {

         link->head=t;

         t->data=data;

         t->next=NULL;

         link->length++;

         return 0;

     }

     else

     {

     p=link->head;

     while(p->next!=NULL)

         p=p->next;

     p->next=t;

     t->data = data;                     //结点数据域赋值

     t->next=NULL;

     link->length++;

     return 0;

     }

}

//删除与查找元素相同的元素函数

int delete_link(link_t * link, int del)

{

     node_t *p,*s;

//利用flag来计算一共有几个与输入元素相同的值

//便于遍历和删除

     int flag=0,leng=0;

//申请新的节点

     p = (node_t *)malloc(sizeof(node_t));

     s = (node_t *)malloc(sizeof(node_t));

     int j=0,i=0,ji=0;

     leng=link->length;

     while(link->head->data==del)

     {

         flag++;

         link->head=link->head->next;

         link->length--;

     }

//直接返回,输出链表

     if(link->length==1)

     return 0;

     p=link->head;

     while(p->next!=NULL)

     {

         if(p->next->data==del)

         {

         flag++;

         }

         p=p->next;

     }

//所有元素均需要删除,直接返回-2,链表为空

     if(flag==leng)

     return -2;

//没有找到需要删除的元素,返回-1,执行插入函数

     else if (flag==0)

     return -1;

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

     {

     ji=0;

     j=0;

     p=link->head;

     while(p->data!=del)

     {

         p=p->next;

         j++;

     }

     p=link->head;

     while(p->next!=NULL&&ji<j-1)

     {

         p=p->next;

         ji++;

     }   

     s=p->next;

     p->next=s->next;

     link->length--;

     }

     return 0;

}

//插入函数

void insert(link_t * link,int ins)

{

     node_t *p,*s;

     //申请新的节点

     p=(node_t*)malloc(sizeof(node_t));

     s=(node_t*)malloc(sizeof(node_t));

     p=link->head;

     while(p->next!=NULL)

     {

         p=p->next;

     }

     s->data=ins;

     s->next=p->next;

     p->next=s;

     link->length++;

}

//打印输出函数

void print(link_t * link)

{

     node_t *p;

     p=(node_t *)malloc(sizeof(node_t));

     int i=0;

     p=link->head;

     for(i=0;i<link->length;i++)

     {

         printf("%d\t",p->data);

         p=p->next;

     }   

}

//主函数

int main()

{

     link_t t;

     t.head=NULL;

     t.length=0;

     int x=0,search=0;

     int r=0,d=0;

     printf("请创建一个单链表(输入0结束)\n");

     printf("请输入一个整数:");

     scanf("%d",&x);

     while (x!=0)

     {

         r=add_link(&t, x);

         if (r==-1)

         {

              printf("链表创建失败!");

              return 0;

         }

         else

         {

         printf("\n请继续输入(整数):");

         scanf("%d",&x);

         }

      }

          printf("链表创建结束!");

          printf("\nlength=%d\n",t.length);

          if (t.length==0)

          {

              printf("您并未创建链表,程序结束"); 

              return 0;

         }

          else

          {

              printf("请输入一个删除或查找的整数:");

              scanf("%d",&search);

              printf("\n原链表为\n");

              print(&t);   

              printf("\n");

              d=delete_link(&t, search);

              if(d==-1)

              {

                   printf("\n您输入的元素不在原链表中,已将其插入链表中。\n新链表为:\n");

                   insert(&t,search);

                   print(&t);

              }

              else if(d==0)

              {

                   printf("\n您输入的元素在原链表中,已将其删除。\n新链表为:\n");

                   print(&t);

              }

              else if(d==-2)

              {

                   printf("\n新链表为空。");

                   return 0;

              }

             

          }

}

 

程序文件名为ex2_2_3.cpp,源程序:

//by郑元帅 2016010901012 通信与信息工程学院  指导教师:居太亮

#include<stdio.h>

#include<stdlib.h>

//定义节点和链表结构体

typedef struct node_t{

     int data;

     struct node_t* next;

}node_t;

typedef struct link_t{

     node_t * head;

     int length;

}link_t;

//模块化,子函数化

//初始化 自定义向量,包含向量长度(<0,=0,>0)判断报错

//返回值1或0,决定程序运行结束与否

//包含增序排序函数,冒泡排序法 ,可独立成子函数

//链表创建函数

int add_link(link_t * link, int data)

{

     node_t *p,*t; 

     p = (node_t *)malloc(sizeof(node_t));   //申请新的结点

     t = (node_t *)malloc(sizeof(node_t));

     if (p==NULL||t==NULL)

         return -1;

     else if(link->head==NULL)

     {

         link->head=t;

         t->data=data;

         t->next=NULL;

         link->length++;

         return 0;

     }

     else

     {

     p=link->head;

     while(p->next!=NULL)

         p=p->next;

     p->next=t;

     t->data = data;                     //结点数据域赋值

     t->next=NULL;

     link->length++;

     return 0;

     }

}

//插入函数;包含冒泡排序法排序。

int insert_link_by_order(link_t * link, int data)

{

     int i=0,j=0;

     node_t *p,*s,*t;

     t=(node_t *)malloc(sizeof(node_t));

     p=(node_t *)malloc(sizeof(node_t));

     s=(node_t *)malloc(sizeof(node_t));

     int temp;

     for(i=1;i<link->length-1;i++)

     {

         p=link->head;

         for(j=0;j<link->length-i;j++)

         {

              if(p->data>p->next->data)

              {

                   temp=p->data;

                   p->data=p->next->data;

                   p->next->data=temp;

              }

              p=p->next;

         }

     }

     p=link->head;

     if(data<=link->head->data)

     {

         t->data=link->head->data;

         t->next=link->head->next;

         link->head->data=data;

         link->head->next=t;

         link->length++;

         return 0;

     }

     else

     {

         p=link->head;

     while(p->next!=NULL)

     {

         if(data<=p->next->data)

         {

              t->data=data;

              t->next=p->next;

              p->next=t;

              link->length++;

              return 0;

         }

         p=p->next;

     }

     //单独处理最后一个元素

     if(data>p->data)

     {

              t->data=data;

              t->next=p->next;

              p->next=t;

              link->length++;

              return 0;

      }

     }

}

// 输出函数

void print(link_t * link)

{

     node_t *p;

     p=(node_t *)malloc(sizeof(node_t));

     int i=0;

     p=link->head;

     for(i=0;i<link->length;i++)

     {

         printf("%d\t",p->data);

         p=p->next;

     }   

}

//主函数,包含错误判断 ,调用子函数

int main()

{

     link_t t;

     t.head=NULL;

     t.length=0;

     int x=0,search=0;

     int r=0,d=0;

     printf("1、请创建一个单链表(输入0结束)\n");

     printf("请输入一个整数:");

     scanf("%d",&x);

     while (x!=0)

     {

         r=add_link(&t, x);

         if (r==-1)

         {

              printf("链表创建失败!");

              return 0;

         }

         else

         {

         printf("\n请继续输入(整数):");

         scanf("%d",&x);

         }

      }

          printf("链表创建结束!");

          printf("\nlength=%d\n",t.length);

         

     printf("\n请输入插入元素(数字):");

     scanf("%d",&x);

     insert_link_by_order(&t,x);

     printf("\n插入元素后的向量:\n");

     print(&t);

}

 

程序文件名为ex2_3_1.cpp,源程序:

#include<stdio.h>

#include<stdlib.h>

//定义节点、链表结构体

typedef struct node_t{

     int data;

     struct node_t* next;

}node_t;

typedef struct link_t{

     node_t * head;

     int length;

}link_t;

//链表创建函数

int add_link(link_t * link, int data)

{

     node_t *p,*t; 

     p = (node_t *)malloc(sizeof(node_t));   //申请新的结点

     t = (node_t *)malloc(sizeof(node_t));

     if (p==NULL||t==NULL)

         return -1;

     else if(link->head==NULL)

     {

         link->head=t;

         t->data=data;

         t->next=NULL;

         link->length++;

         return 0;

     }

     else

     {

     p=link->head;

     while(p->next!=NULL)

         p=p->next;

     p->next=t;

     t->data = data;                     //结点数据域赋值

     t->next=NULL;

     link->length++;

     return 0;

     }

}

//删除负数函数

int delete_link(link_t * link)

{

     node_t *p,*s;

     int flag=0,leng=0,flagf=0;

     p = (node_t *)malloc(sizeof(node_t));

     s = (node_t *)malloc(sizeof(node_t));

     int j=0,i=0,ji=0;

     leng=link->length;

     while(link->head->data<0)

     {

         flag++;

         flagf++;

         link->head=link->head->next;

         link->length--;

         if(link->length==0)

         return -1;//链表已空

     }

     if(link->length==1)

     return 0;

     p=link->head;

     while(p->next!=NULL)

     {

         if(p->next->data<0)

         {

         flag++;

         }

         p=p->next;

     }

     if(flag==leng||link->length==0)

     return -1;//链表已空

     else if (flag==0)

     return -2;//原链表没有负数

     for(i=0;i<flag-flagf;i++)

     {

     ji=0;

     j=0;

     p=link->head;

     while(p->data>=0)

     {

         p=p->next;

         j++;

     }

     p=link->head;

     while(p->next!=NULL&&ji<j-1)

     {

         p=p->next;

         ji++;

     }    //移动到需要删除的元素前面

     s=p->next;

     p->next=s->next;

     link->length--;

     }

     return 0;//删除成功

}

//打印输出函数

void print(link_t * link)

{

     node_t *p;

     p=(node_t *)malloc(sizeof(node_t));

     int i=0;

     p=link->head;

     for(i=0;i<link->length;i++)

     {

         printf("%d\t",p->data);

         p=p->next;

     }   

}

//主函数

int main()

{

     link_t t;

     t.head=NULL;

     t.length=0;

     int x=0,r=0,f=0;

     printf("请创建一个单链表\n");

     printf("请输入一个整数:");

     scanf("%d",&x);

     while (x!=0)

     {

         r=add_link(&t, x);

         if (r==-1)

         {

              printf("链表创建失败!");

              return 0;

         }

         else

         {

         printf("\n请继续输入(整数):");

         scanf("%d",&x);

         }

     }

          printf("链表创建结束!");

          printf("\nlength=%d\n",t.length);

          if (t.length==0)

          {

              printf("您并未创建链表,程序结束"); 

              return 0;

         }

          else

          {

 

              f=delete_link(&t);

              if (f==-1)

              {

                   printf("链表已空,结束");

                   return 0;

              }

              else if (f==-2)

              {

                   printf("链表中无负数");

                   return 0;

              }

              else

              {

                  printf("程序将删除单链表中的负数,新链表为:\n");

                   print(&t);   

              }

          }

}

 

程序文件名为ex2_3_2.cpp,源程序:

#include <stdio.h>

#include<stdlib.h>

#include <string.h>

//定义链表结构体

typedef struct link_t

{

     int data;

     struct link_t *prior;

     struct link_t *next;

}link_t;

//排序函数;冒泡排序法;交换p与pr(p前)

void sort(link_t *head)

{

     link_t *p = head->next;

     link_t *tail = NULL;

     link_t *pr=head;

     link_t *t=NULL;

     while(head->next!=tail)

    { 

        p=head->next; 

        pr=head; 

        while(p->next!=tail) 

        { 

            if((p->data)>(p->next->data)) 

            {                   

                pr->next=p->next;  

                t=p->next->next; 

                p->next->next=p; 

                p->next=t; 

                p=pr->next;  //p回退一个节点  

                 

            } 

            p=p->next;  //p再前进一个节点  

            pr=pr->next;    

        }  

        tail=p;

    } 

}

//打印排序后结果

void print_list(link_t *head)

{

link_t *p = head->next;

while(p != NULL)

{

     printf("%d\t", p->data);

     p = p->next;

}

}

//主函数;包含创建函数

int main()

{

     int i=0,x=0;

     link_t *head = (link_t *)malloc(sizeof(link_t));

     link_t *p = NULL;

     head->prior = head->next = NULL;

     printf("请输入双向链表元素(整数):\n");

     scanf("%d",&x);

     if(x==0)

     {

         printf("链表为空,结束");

         return 0;

     }

     else

     while(x!=0)

     {

     p = (link_t *)malloc(sizeof(link_t));

     p->data = x;

     p->next = head->next;

     if(head->next != NULL)

         head->next->prior = p;

     head->next = p;

     p->prior = head;

     printf("请继续输入:\n");

     scanf("%d",&x);

     }

     printf("链表创建结束。");

     printf("\n链表序列为:\n ");

     print_list(head);

     sort(head);

     printf("\n排序后链表序列为:\n ");

     print_list(head);

}

ex3_1:链栈——基本题

1)链栈结点类型定义为:

   typedef struct node

     {

            int  data;

            struct node *next;

     }node_type;

2)编写进栈函数push

3)编写出栈函数pop

4)编写main函数,首先建立一空链栈;

    调用进栈函数,将从键盘输入的数据元素逐个进栈,输入0结束;显示进栈后的数据元素;

调用两次出栈函数,显示出栈后的数据元素。

ex3_2:循环队列——基本题

1)顺序循环队列类型定义为:

#define N 20

typedef struct

{     int data[N];

       int front, rear;

}queue_type;

2)编写循环队列出队函数dequeue

3)编写循环队列入队函数enqueue

4)编写函数:void aa(queue_type *q);

     其功能为,调用出队函数把队列q中的元素一一出队,如果是负数直接抛弃;如果是正数,则调用入队函数,插入到q的队尾。

5)编写main函数,首先建立一个队列,其中的数据元素为:{2, 3, -4, 6, -5, 8, -9, 7, -10, 20};然后调用aa函数,并将aa函数调用前后队列的数据元素分别输出到屏幕上。

Ex3_1

  1. 程序流程说明:

建立链栈

——>

建立入栈函数

——>

建立出栈函数

——>

编写输出函数

  1. 程序文件名为ex3_1.cpp,源程序清单如下:

#include<stdio.h>

#include<stdlib.h>

typedef struct node

{

     int data;

     struct node *next;

 }node_type;

 void init(node **top)

 {

     (*top)->next=NULL;

 }

 void push(node **top,int x)

 {

     node *p;

     p=(node*)malloc(sizeof(node));

     p->data=x;

     p->next=(*top);

     (*top)=p;

 }

 void pop(node **top)

 {

     node *p;

     int x;

     if((*top)==NULL)

     {

         printf("栈已空。");

         return ;

      }

     x=(*top)->data;

     p=(*top);

     (*top)=(*top)->next;

     free(p);

     return ;

 }

 void print(node **top)

 {

     node *p=(node *)malloc(sizeof(node));

     p=(*top);

     while(p->next!=NULL)

     {

         printf("%d\t",p->data);

         p=p->next;

      }

 }

 int main()

 {

     int x=0,length=0;

     node *top = (node *)malloc(sizeof(node));

     init(&top);

     printf("请建立链栈(输入0结束):\n");

     scanf("%d",&x);

     while(x!=0)

     {

         push(&top,x);

         printf("请继续输入入栈元素:\n");

         scanf("%d",&x);

         length++;

      }

      //printf("%d",length);

     printf("链栈建立完成。\t");

     printf("\n目前栈内元素为:\n");

     print(&top);

     printf("\n目前栈内元素个数为:");

     printf("%d\n",length);

     if(length>2)

     {

     pop(&top);

     pop(&top);

     printf("\n调用两次出栈函数后栈内的数据元素为:\n");

     print(&top);

     }

     else if(length==2)

     {

     pop(&top);

     pop(&top);

     printf("\n调用两次出栈函数后栈内的数据元素为空\n");    

      }

     else if(length==1)

     {

         pop(&top);

         printf("\n调用一次出栈函数后栈内的数据元素为空\n");

         print(&top);

     }

     else

     {

         printf("栈为空!");

         return 0;

     }   

 }

Ex3_2

1.   程序流程说明:

建立队列

——>

调用aa函数

——>

一一出队

——>

判断正负

——>

负数抛弃,正数入队尾

——>

输出原队列和新队列

2.程序文件名为ex3_2.cpp,源程序清单如下:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define N 20

typedef struct

{

     int data[N];

     int front,rear;

}queue;

//初始化队列

void init(queue *q)

{

     q->front=0;

     q->rear=0;

 }

 //循环队列入队函数

int enqueue(queue *q,int x)

{

     if((((q->rear)+1)%N)==q->front)

     return 0;

     else

     {

         q->rear=(q->rear+1)%N;

         q->data[q->rear]=x;

         return 1;

     }

}

//循环队列出队函数

int dequeue(queue *q)

{

     if(q->rear==q->front)

     return -1;

     else

     {

         q->front=(q->front+1)%N;

         return (q->data[q->front]);

      }

}

//aa函数:一一出队,负数抛弃,正数入队

void aa(queue *q)

{

     int t=0;

     int flag=q->rear;

     for(;flag>0;flag--)

     {

     t=dequeue(q);

     if(t<0)

     continue;

     else if(t>0)

         enqueue(q,t);

     }

}

//主函数

int main()

{

     queue t;

     int leng=0,temp=0;

     int i=0;

     init(&t);

     int a[20]={2,3,-4,6,-5,8,-9,7,-10,20};

     while (a[leng]!=0)

     {

         leng++;

     }

     //printf("leng=%d\n",leng);

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

     {

         temp=a[i];

         enqueue(&t,temp);

     }

     //printf("t.rear=%d\n",t.rear);

     for (i=1;i<leng+1;i++)

     {

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

     }

     aa(&t);

     printf("\n");

     for (i=t.rear;t.rear>t.front;t.rear--)

     {

         printf("%d\t",t.data[t.rear]);

     }

    

}

ex3_3:教材第一章习题12题——扩展题

1)两个栈共用一个数组空间,它们的栈底分别在数组两端,栈顶相向而行。编写入栈和出栈函数,实现两个栈元素分别的(但共用)入栈和出栈。

2)main中函数完成以下测试:

a、能否在共用空间上实现两个独立的栈:即能否向两个栈分别输入元素;能否分别从两个栈取出元素,每个栈取出的元素的顺序符合各自栈的特点

b、能否在共用空间用满时,及时制止新的入栈行为。

例如:

        假设数组大小为6,main函数实现以下动作,向栈1接连入栈4个元素后,向栈2入栈2个元素致栈满,再向栈2输入一个元素,将报错。接着从栈1出栈1个元素,再向栈2入栈,就会成功。最后,两个栈分别出空,观察输出顺序是否满足栈的特点。

ex3_4:教材第一章习题13题——扩展题

1)实现一种扩展的循环队列,使得全部的数组空间都能使用,基本思路是当传统循环队列放满时:即

                     (rear+1)%MAXNUM ==front  为真

时,可以再入队一个元素,接着rear = (rear+1)%MAXNUM后就会与front相等,此时将另外一个变量flag设置为1,表示此时的rear==front不是为空,而是满。否则flag为0时,如果出现rear==front,则表示队列为空。

2)main()函数实现以下测试:

a、能否实现全部“装满”,即装入元素个数为MAXNUM

b、能否按照循环队列那样绕着存放空间循环存放。

c、能否在装满后,拒绝再装。

d、能否在装满后,不会变成“空”的——即可以还可正常出队。

e、能否在全部出空后,不会变成“满”的——即可还可正常入队。

例如:

        假设循环队列最大空间为5,main()函数实现以下动作,接连成功入队5个元素,入队第6个元素时,报错。接着出队3个元素,入队3个元素,均成功。再入队1个,报错。继续连续成功出队6个元素,出队第7个时报错。最后,再成功入队2个元素。

ex3-5——扩展题(选做)

利用栈实现算术四则运算,即录入一个包含加减乘除运算的多项式,计算出结果。暂不考虑“括号”。

本题算法难点在如何利用栈,驱动运算过程。

本题程序难点在从输入的一个形如“3+4×16-4/3”的字符串中依次提取出各个数字和运算符——可利用CString。

ex3-6——教材(第5版例5)扩展题(选做)

计算并输出二项展开式(a+b)n的各项系数,即求一个杨辉三角形的最下面一层所有元素。

本题算法难点在利用杨辉三角形计算原理,不断利用队列在上一层元素的基础上,求出下一层元素。

  1. 程序文件名为ex3_3.cpp,源程序清单如下:

#include<stdio.h>

//by 郑元帅  2016010901012 指导教师:居太亮

struct STACK

{

     int stack[1000];

     int top0,top1;

}stack_int;

int m=0;

//初始化函数

void init(STACK *p,int m)

{

     p->top0=0;

     p->top1=m-1;

}

//入栈函数

void push(STACK *p,int i,int data)

{

     //printf("%d",p->top0);

     //printf("%d",p->top1);

     if (i==0)

     {

         if(p->top0<0||p->top0>p->top1)

         {

              printf("\nerror!pre栈已满,已无法入栈!\n");

         }

         else

         {

         //printf("attention place");

         p->stack[p->top0]=data;

         p->top0++;

         }

     }

     else if (i==1)

     {

         if(p->top1<p->top0)

         {

              printf("error,pre栈满!");

         }

         else

         {

         p->stack[p->top1]=data;

         p->top1--;

         }

     }

}

//出栈函数

int pop(STACK *p,int i,int m)

{

     if (i==0)

     {

         if(p->top0<0)

         {

              printf("栈空!\n");

              return NULL;

         }

         else

         {

         p->top0--;

         if(p->top0<0)

         {

              printf("栈空!\n");

              return NULL;

         }

         else

         return p->stack[p->top0];

         }

     }

     else if (i==1)

     {

         //printf("m=%d\n",m);

         //printf("top1=%d\n",p->top1);

         if(p->top1>m-1)

         {

              printf("栈空!\n");

              return NULL;

         }

         else

         {

         p->top1++;

//       if(p->top1==-1)

//       p->top1=0;

         if(p->top1>m-1)

         {

              printf("栈空!\n");

              return NULL;

         }

         else

         return p->stack[p->top1];  

         }

     }

     else

     {

         return NULL;

     }

}

//主函数

int main()

{

     STACK stack_int;

     int x=0,i=0,m=0,data=0,a=0,flag=0,t=0;

     printf("请输入一维数组的长度(>=0的自然数):");

     scanf("%d",&m);

     init(&stack_int,m);

     if (m<0)

     {

         printf("长度不符合要求");

         return 0;

      }

     else

     {

         printf("数组长度初始化成功,length=%d\n",m);

         printf("\n请输入需要进行的操作:\n");

         printf("1、向栈1入栈。\n2、向栈2入栈。\n3、栈1出栈。\n4、栈2出栈。\n5、退出\n");

         scanf("%d",&flag);

         while(1)

         {   

              if(flag==1)

                       {

                            printf("请输入向栈1入栈的元素:\n");

                            scanf("%d",&data);

                            push(&stack_int,0,data);

                            //printf("入栈成功!");

                       }

              else if(flag==2)

                       {

                            printf("请输入向栈2入栈的元素:\n");

                            scanf("%d",&data);

                            push(&stack_int,1,data);

                            //printf("入栈成功!");

                       }

              else if(flag==3)

                       {

                            a=pop(&stack_int,0,m);

                            printf("出栈元素为:\n%d",a);

                       }

              else if(flag==4)

                       {

                            a=pop(&stack_int,1,m);

                            printf("出栈元素为:\n%d",a);

                       }

              else

                       {

                            printf("程序已成功退出。");

                            return 0;

                       }

         printf("\n请输入需要进行的操作:\n");

         printf("1、向栈1入栈。\n2、向栈2入栈。\n3、栈1出栈。\n4、栈2出栈。\n5、退出\n");

         scanf("%d",&flag);

              }

     }

}

Ex3_4

1.   程序流程说明:

初始化queue长度

——>

1、入队函数

——>

2、出队函数

——>

3、循环执行操作

——>

退出

2.程序文件名为ex3_4.cpp,源程序清单如下:

 

#include <stdio.h>

#define M 5

//by 郑元帅 软循环队列算法 2016010901012 指导教师:居太亮

//这里tag=0表示队列为空,tag=1表示队列已满(均有操作提示)

//增加了tag=3的语句,目的:使得在队列未满或者未空状态下能够自由进行入队出队操作

//使之与相关判断兼容,提高容错性。

int main()

{

     int queue[M];

     int tag = 0;

     int flag=0;//用户输入指令

     int front = 0;

     int rear=0;

     int x=0;//入队列元素

     int l=0;

     printf("请选择要执行的操作:\n1:入队\n2:出队\n3:退出\n");

     scanf("%d",&flag);

//诸多判断,提高容错性,给用户详细的操作说明。

     if(flag==2)

     {

         printf("error:队列为空,不可执行出队操作");

         return 0;

     }

     else if(flag<1&flag>3)

     {

         printf("error:输入指令错误");

         return 0;

     }

     else if(flag==3)

     {

         printf("\n已退出");

         return 0;

     }

     else

     {

     while(flag!=3)

     {

         if(flag==1)

         {

              if(tag!=1)

              {

                   printf("请输入入队数值:");

                   scanf("%d",&x);

                   queue[rear%M]=x;

                   rear=(rear+1)%M;//队尾指针增加

                   tag=3;//使得在队列未满或者未空状态下能够自由进行入队出队操作

                   l++;//长度计算

                   if(rear == front)

                   {

                       tag = 1;

                       //printf("队列已满\n");

                   }

                      

              }

         }

         else if(flag == 2)

         {

              if(tag!=0)

              {

                   printf("出队数值为:%d\n",queue[front]);

                   front=(front+1)%M;

                   if(rear == front)

                   {

                       tag = 0;

                       //printf("队列已空\n");

                   }       

              }

 

         }

              printf("请选择要执行的操作:\n1:入队\n2:出队\n3:退出\n");

              scanf("%d",&flag);

              if(tag==0&flag==2)

              {

              printf("error:队列已空,不可执行出队操作\n");

              tag=3;

              printf("请选择要执行的操作:\n1:入队\n2:出队\n3:退出\n");

              scanf("%d",&flag);

//                 return 0;

              }

              else if(tag==1&flag==1)

              {

              printf("error:队列已满,不可执行入队操作\n");

              tag=3;

              printf("请选择要执行的操作:\n1:入队\n2:出队\n3:退出\n");

              scanf("%d",&flag);

//                 return 0;

             }

             else if(flag>3||flag<1)

             {

             printf("error:输入指令错误");

//           return 0;

              }

              else if(flag==3)

              {

                   printf("已退出");

                   return 0;

              }

             else

             continue;

     }

    }

     return 0;

}

Ex3_5

1.   程序流程说明:

定义数字入栈出栈,符号入栈出栈函数

——>

定义输入函数

——>

定义加减乘除入栈顺序函数

——>

定义中缀和后缀转换函数

——>

定义计算函数

——>

结束

2.程序文件名为ex3_5.cpp,源程序清单如下:

#include<stdio.h>

#include<string.h>

#include<ctype.h>

#include<stdlib.h>

//by 郑元帅 UESTC 软件技术实验 指导教师:居太亮

//程序利用中缀和后缀转换和后缀的四则运算实现。

//定义栈的结构体

#define max 100

typedef struct stack_t{

     int num=0;

     char ope='=';

     int isnum=0;

}stack;

//定义中缀和后缀栈

stack median[max];

stack after[max];

//定义数字和符号的存储数组

double stacknum[max];

char stackope[max];

int numtop=0;

int opetop=0;

//定义符号入栈函数

void pushope(char ope)

{

     stackope[opetop++]=ope;

}

//定义符号入栈函数,返回字符型变量

char popope()

{

     return stackope[--opetop];

}

//定义数字入栈函数

void pushnum(double data)

{

     stacknum[numtop++]=data;

}

//定义数字出栈函数,返回double型变量

double popnum()

{

     return stacknum[--numtop];

}

//定义输入函数

int get()

{

     //定义输入存储字符数组

     char input[max];

     printf("请输入四则运算式");

     gets(input);

//   if(input[0]=='c')

//       return 0;

     //num为多位数变量

     int num=0;

     for (int i=0,j=0;i<max;i++)

     {

         //获得多位数

         if(isdigit(input[i]))

         {

              num=num*10+input[i]-'0';

         }

         else

         {

              if(input[i]=='=')

              {

                   if(input[i-1]!='=')

                   {

                   //将num的数值放入中缀栈中,并将中缀设置为1

                   median[j].isnum =1;

                   median[j++].num=num;

                   //num置零

                   num=0;

                   }

                   //否则,将中缀设置为0,未结束

                   //将中缀符号设置为=

                   median[j].isnum=0;

                   median[j++].ope='=';

                   break;

              }

              //判断括号(不要求),如果是左括号,则在中缀栈中放入左括号,并将符号置零

              else if(input[i]=='(')

              {

                   median[j].isnum=0;

                   median[j++].ope='(';

              }

              //判断右括号,如果是右括号,则在中缀栈中放入右括号,并将符号置零 

              else if(input[i]==')'&&input[i-1]==')')

              {

                   median[j].isnum=0;

                   median[j++].ope=')';

              }

              //其他符号,将中缀符号置1,将数字放入中缀栈 中,将符号放入中缀站中。

              else

              {

                   median[j].isnum=1;

                   median[j++].num=num;

                   num=0;

                   median[j].isnum=0;

                   median[j++].ope=input[i];

              }

        

         }

     }

     //输出查看中缀栈内元素

     for(int i=0;i<max;++i)

     {

         if(!median[i].isnum&&median[i].ope=='=')

         {

              printf("%c\n",'=');

              break;

         }

         //中缀符号为1时,输出数字,中缀符号为0时,输出符号

         else if (median[i].isnum)

         {

              printf("%d",median[i].num);

         }

         else

         {

              printf("%c",median[i].ope);

         }

     }

     return 1;

}

//声明子函数

void isadd(int *j);

void issub(int *j);

void ismulti();

void isdiv();

void isleft();

void isright(int *j);

void isequal(int *j);

//中缀与后缀转换函数

void translate()

{

     int i=0;

     int j=0;

     for(i=0,j=0;i<max;++i)

     {

         //判断数字,置入后缀栈中

         if(median[i].isnum)

         {

              after[j].isnum=1;

              after[j++].num=median[i].num;

         }

         else

         {

              switch(median[i].ope)

              {

                   case '(':

                        isleft();

                       break;

                   case ')':

                       isright(&j);

                       break;

                   case '+':

                       isadd(&j);

                       break;

                   case '-':

                       issub(&j);

                       break;

                   case '*':

                       ismulti();

                       break;

                   case '/':

                       isdiv();

                       break;

                   case '=':

                       isequal(&j);

                       return; 

              }

         }

     }

}

//左边,直接入栈

void isleft()

{

     pushope('(');

}

//右边,出栈,后缀符号入栈,置零

void isright(int *j)

{

     char ope;

     while(opetop>0)

     {

         ope=popope();

         if(ope=='(')

         return ;

         else

         {

              after[(*j)].isnum=0;

              after[(*j)++].ope=ope;

         }

     }

}

//加法,出栈,后缀符号入栈

void isadd(int *j)

{

     char ope;

     while(opetop>0)

     {

         ope=popope();

         if(ope==')')

         {

              pushope(ope);

              break;

         }

         else

         {

              after[(*j)].isnum=0;

              after[(*j)++].ope=ope;

         }

     }

     pushope('+');

}

//减法,出栈,后缀符号入栈

void issub(int *j)

{

     char ope;

     while(opetop>0)

     {

         ope=popope();

         if(ope=='(')

         {

              pushope(ope);

              break;

         }

         else

         {

              after[(*j)].isnum=0;

              after[(*j)++].ope=ope;

         }

     }

     pushope('-');

}

//乘法子函数,直接入栈

void ismulti()

{

     pushope('*');

}

//除法子函数,直接入栈

void isdiv()

{

     pushope('/');

}

//等号,后缀入栈,符号置零

void isequal(int *j)

{

     char ope;

     while(opetop>0)

     {

         ope=popope();

         after[(*j)].isnum=0;

         after[(*j)++].ope=ope;

     }

     after[(*j)].isnum=0;

     after[(*j)++].ope='=';

}

//计算函数

double calculate()

{

     int i=0;

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

     {

         //输出后缀表达式

         if(!after[i].isnum&&after[i].ope=='=')

         {

              printf("%c\n",'=');

              break;

         }

         else if(after[i].isnum)

         {

              printf("%d",after[i].num);

         }

         else

         {

              printf("%c",after[i].ope);

         }

     }

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

     {

         if(!after[i].isnum&&after[i].ope=='=')

         {

              return popnum();

         }

         else if(after[i].isnum)

         {

              pushnum((double)(after[i].num));

         }

         else

         {

              //非=,分别出栈两个,利用后缀中的符号判断运算,将两个数值运算,并将结果入栈

              double temp=0.0;

              double rear=popnum();

              double front=popnum();

             

              switch(after[i].ope)

              {

                   case '+':

                       temp=front+rear;

                       pushnum(temp);

                       break;

                   case '-':

                       temp=front-rear;

                       pushnum(temp);

                       break;

                   case '*':

                       temp=front*rear;

                       pushnum(temp);

                       break;

                   case '/':

                       temp=front/rear;

                       pushnum(temp);

                       break;

              }

         }

     }

     return 0;

}

//主函数

int main()

{

     while(1)

     {

         if(get())

         {

              //调用转换和运算函数

              translate();

              double result=calculate();

              printf("result is %lf\n",result);

         }

         else

              break;

     }

     return 0;

}

Ex3_6

1.   程序流程说明:

自定义二项式指数

——>

将各项系数初始化为1

——>

入基本元素到队列指定位置

——>

将第m行的非1元素利用规律进行计算

——>

将计算结果入队列相应位置

——>

下一行利用上一行元素出队列后进行操作

——>

以此类推

——>

将各项系数补齐

——>

输出并结束

2.程序文件名为ex3_6.cpp,源程序清单如下:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define N 100

typedef struct

{

     int data[N];

     int front,rear,cir;

}queue;

//初始化队列

void init(queue *q)

{

     q->front=0;

     q->rear=0;

     q->cir=0;

 }

 //入队操作

int enqueue(queue *q,int x)

{

         q->data[q->rear]=x;

         q->rear=(q->rear+1)%N;

         return 1;

}

//出队操作

int dequeue(queue *q)

{

     int temp=0;

         temp=q->data[q->cir];

         q->front=(q->front+1)%N;

         q->cir=(q->cir+1)%N;

         return (temp);

}

//主函数

int main()

{

     queue t;

     int n=0,x1=0,x2=0;

     int i=0,j=0;

     int a=0,u=0;

     int p=0,k=0;

     int output=0;

     int number=0;

     init(&t);

     printf("请输入(a+b)^n中的n:");

     scanf("%d",&n);

     printf("二项展开式的各项系数为:\n");

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

     {

         enqueue(&t,1);    

     }

     t.rear=0;

     enqueue(&t,1);

     enqueue(&t,1);

     enqueue(&t,1);

     enqueue(&t,1);

//   printf("rear=%d\n",t.rear);

     for(int m=3;m<=n;m++)

     {

     p=m*(m-1)/2;

     for(k=1;k<=m-2;k++)

     {

     for(j=0;j<=p+k-m;j++)

     {

         x1=dequeue(&t);

 

     }   

     x2=dequeue(&t);

     //printf("x1=%d\t",x1);

//   printf("x2=%d\n",x1);

     //printf("front=%d\n",t.front);

     t.cir=0;

     t.data[p+k]=x1+x2;

     enqueue(&t,t.data[p+k]);

     //printf("t-data[%d]=%d\n",p+k,t.data[p+k]);

     }

     if(t.rear==m*(m+1)/2-1)

     {

         enqueue(&t,1);

         enqueue(&t,1);

     }

     }

//       printf("t-data[%d]=%d\n",p+k,t.data[6]);

     t.front=0;

     for(i=0;i<n*(n-1)/2;i++)

     {

         output=dequeue(&t);

     }

     //printf("front=%d\n",t.front);

     printf("\n\n___________________________________\n\n\n");

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

     {

         output=dequeue(&t);

         printf("%d\t",output);

     }

     printf("\n\n___________________________________\n\n\n");

}

程序流程说明:

初始化二叉树

——>

建立插入函数,构造二叉排序树

——>

中序遍历二叉树

——>

先序遍历二叉树

——>

后序遍历二叉树

——>

编写二叉树搜索函数,查找指定数据元素

——>

释放存储空间

  1. 程序文件名为tree.cpp,源程序清单如下:

/*******************************Copyright (c)*********************************************

**                University of Electronic Science and Technology of China

**                  School of Communication and Information Engineering

**                          http://www.uestc.edu.cn

**

**--------------------------- File Info ---------------------------------------------------

** File name:           tree.cpp

** Last modified Date:  2012-12-19

** Last Version:        1.0

** Descriptions:        各种二叉树操作,二叉树结构的定义在mystruct.h中,

**                      函数中使用的与界面显示有关接口的说明在ui.h

**                      本文件基于C语言风格

**------------------------------------------------------------------------------------------

** Created by:          Duan Jingshan

** Created date:        2012-12-19

**------------------------------------------------------------------------------------------

** Modified by:  

** Modified date:

** Version:   

** Descriptions: 

**

*******************************************************************************************/

#include "stdafx.h"

#include "mystruct.h"

#include "ui.h"

/*******************************************************************************************

** Function name: init_tree()

** Descriptions    :    初始化二叉树

**                  二叉树的是非线性结构,大多数情况下采用链接存储,采用动态申请内存的方式

**                  在需要的时候为链点申请空间。二叉树结构中最重要的是根节点指针,因此在初

**                  始化时,除了要申请二叉树结构空间外,还应将其中的根节点指针设置为空

** Input: NONE

** Output:  NONE

**   return:  类型:tree_t *,返回链表的结构指针

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

tree_t * init_tree()

{

     tree_t * t = (tree_t *)malloc(sizeof(tree_t));;

     t->num=0;

     t->root=NULL;

     return t;

}

/*******************************************************************************************

** Function name: free_tree()

** Descriptions    :    释放二叉树结构

**                  当程序结束时会通过本函数来释放二叉树空间,如果二叉树中有多个元素,则需要

**                  逐个将元素的空间予以释放。

** Input: tree_t * t; 链表结构指针

** Output:  NONE

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void free_tree(tree_t * tree)

{

     if(tree == NULL){

         return;

     }

    

     free_tree_nodes(tree->root);

     free(tree);

     return;

}

/*******************************************************************************************

** Function name: free_tree_nodes()

** Descriptions    :    释放二叉树的所有链点

**                  当程序结束时会通过本函数来释放二叉树空间,如果二叉树中有多个元素,则需要逐个将

**                  元素的空间予以释放,由于二叉树是非线性结构,可以考虑采用后根遍历递归框架释放

**                  各个链点,采用后根的原因是根节点的空间不能早于子树节点空间释放,否则无法继续

**                  继续遍历链表

** Input: tnode_t * root; 二叉树根结点指针

** Output:  NONE

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void free_tree_nodes(tnode_t * root)

{

     if(root == NULL){

         return;

     }

     if(root->Lchild != NULL)

         free_tree_nodes(root->Lchild);

     if(root->Rchild != NULL)

         free_tree_nodes(root->Rchild);

     free(root);

     return;

}

/*******************************************************************************************

** Function name: insert_BS_tree()

** Descriptions    :    向二叉排序树插入一个元素,以元素中的数据项——总分作为排序码

** Input:

**          tree_t * tree; 二叉树指针

**          element data; 新元素

** Output:  NONE

**   return:  类型:int,0,表示成功插入;-1,表示插入失败,一般是因为没有足够的内存

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int insert_BS_tree(tree_t * tree, element_t data)

{

     tnode_t *dr=(tnode_t *)malloc(sizeof(tnode_t));

     tnode_t *pr=(tnode_t *)malloc(sizeof(tnode_t));

     //tnode_t *pr_l=(tnode_t *)malloc(sizeof(tnode_t));

     //tnode_t *pr_r=(tnode_t *)malloc(sizeof(tnode_t));

     //pr->Lchild=NULL;

     //pr->Rchild=NULL;

     if(tree->root==NULL)

     {

         dr->data=data;

         dr->Lchild=NULL;

         dr->Rchild=NULL;

         tree->root=dr;

         tree->num++;

     }

     else

     {

         dr=tree->root;

         while(dr!=NULL)

         {

              if(data.overall<dr->data.overall)

              {

                  

                   if(dr->Lchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Lchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Lchild;

              }

              else

              {

                   //   dr=dr->Rchild;

                   if(dr->Rchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Rchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Rchild;

              }

         }

         //if(data.overall<pr->data.overall)

         //   pr->Lchild->data=data;

         //else

         //   pr->Rchild->data=data;

         //if(data.overall<dr->data.overall)

         //dr->Lchild->data=data;

         //else

         //   dr->Rchild->data=data;

     }

     return 0;

}

/*******************************************************************************************

** Function name: inorder_tree()

** Descriptions    :    中序(根)遍历一棵二叉树,

**                  在访问节点内容时,调用ui.h中的ShowElement()来将元素内容显示在窗口内

**                  以供检查

** Input:

**          tnode_t * root; 二叉树指针

** Output:  NONE

**

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void inorder_tree(tnode_t * root)

{

     if(root==NULL)

         return;

     else

     {

         if(root->Lchild!=NULL)

         {

              inorder_tree(root->Lchild);

         }

         ShowElement(root->data);

         if(root->Rchild!=NULL)

         {

              inorder_tree(root->Rchild);

         }

     }

}

/*******************************************************************************************

** Function name: preorder_tree()

** Descriptions    :    先序(根)遍历一棵二叉树,

**                  在访问节点内容时,调用ui.h中的ShowElement()来将元素内容显示在窗口内

**                  以供检查

** Input:

**          tnode_t * root; 二叉树指针

** Output:  NONE

**

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void preorder_tree(tnode_t * root)

{

     if(root==NULL)

         return;

     else

     {

         ShowElement(root->data);

         if(root->Lchild!=NULL)

         {

              preorder_tree(root->Lchild);

         }

         if(root->Rchild!=NULL)

         {

              preorder_tree(root->Rchild);

         }

     }

}

/*******************************************************************************************

** Function name: postorder_tree()

** Descriptions    :    后序(根)遍历一棵二叉树,

**                  在访问节点内容时,调用ui.h中的ShowElement()来将元素内容显示在窗口内

**                  以供检查

** Input:

**          tnode_t * root; 二叉树指针

** Output:  NONE

**

**   return:  类型:void

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void postorder_tree(tnode_t * root)

{

     if(root==NULL)

         return;

     else

     {

         if(root->Lchild!=NULL)

         {

              postorder_tree(root->Lchild);

         }

         if(root->Rchild!=NULL)

         {

              postorder_tree(root->Rchild);

         }

         ShowElement(root->data);

     }

     return ;

}

/*******************************************************************************************

** Function name: get_element_tree()

** Descriptions    :    在二叉树中,查询指定学号的元素,获得该元素的链点指针,以备进一步访问所需

**                  查询算法需要对二叉树进行遍历,可采用先序(根)遍历算法的框架,

** Input:

**          tnode_t * root; 二叉树指针

**          double stuID; 学号

** Output:  NONE

**

**   return:  类型:tnode_t *; 返回具有指定学号的链点指针,如果没找到则返回值为NULL

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

tnode_t * get_element_tree(tnode_t * root, double stuID)

{

     tnode_t * ret = NULL;

     tnode_t * retr = NULL;

     tnode_t *p=NULL;

     p=root;

//    while(p!=NULL)

//   {

 //       if(stuID==p->data.stuID)

//        {

//            return p;   

//        }   

 //       else if(stuID<p->data.stuID){

 //           p = p->Lchild;   

 //       }

 //       else{

  //          p = p->Rchild;   

 //       }

 //   }

 //   if(p == NULL)

//   {

 //       return NULL;  

 //   }

     if(p==NULL)

         return NULL;

     else

     {

         if(p->data.stuID==stuID)

              return root;

         if(p->Lchild!=NULL)

         {

              tnode_t * ret = NULL;

              ret=p->Lchild;

              if(ret->data.stuID==stuID)

                   return ret;

              else

                   get_element_tree(ret, stuID);

         }

         if(p->Rchild!=NULL)

         {   

              tnode_t * retr = NULL;

              retr=p->Rchild;

              if(retr->data.stuID==stuID)

                   return retr;

              else

                   get_element_tree(retr, stuID);

         }

     }

}

六、     实验内容:

ex4_2——扩展题

1)实现二叉排序树的插入函数

2)main函数中,输入一组无序数,调用二叉排序树插入算法,将元素放入二叉树中

3)中序遍历这颗二叉树,得到排序顺序。

ex4-3——扩展题

2)  编写函数求一颗二叉树的深度

2)求一颗二叉排序树的排序的反序结果,即将二叉排序树每个节点的左右子树交换,然后中序遍历之。

ex4-4——扩展题(选做)

1)输入一组数(权值),编写建立哈夫曼树的函数

2)以先序遍历为框架,输出每个权值对应的二进制编码

Ex4_2

  1. 程序流程说明:

二叉树初始化

——>

插入构造二叉树

——>

中序遍历

  1. 程序文件名为ex4_2.cpp,源程序清单如下:

 #include<stdio.h>

#include<stdlib.h>

//ex4_2——扩展题

//1)实现二叉排序树的插入函数

//2)main函数中,输入一组无序数,调用二叉排序树插入算法,将元素放入二叉树中

//3)中序遍历这颗二叉树,得到排序顺序。

typedef struct tnode_t{

     int data;

     struct tnode_t * Lchild;

     struct tnode_t * Rchild;

}tnode_t;

typedef struct tree_t{

     tnode_t * root;

     int num;

}tree_t;

//初始化二叉树

 

void init_tree(tree_t *t)

{

     t->num=0;

     t->root=NULL;

}

//二叉排序树插入函数

int insert_BS_tree(tree_t * tree, int data)

{

     tnode_t *dr=(tnode_t *)malloc(sizeof(tnode_t));

     tnode_t *pr=(tnode_t *)malloc(sizeof(tnode_t));

     if(tree->root==NULL)

     {

         dr->data=data;

         dr->Lchild=NULL;

         dr->Rchild=NULL;

         tree->root=dr;

         tree->num++;

     }

     else

     {

         dr=tree->root;

         while(dr!=NULL)

         {

              if(data<dr->data)

              {

                  

                   if(dr->Lchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Lchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Lchild;

              }

              else

              {

                   if(dr->Rchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Rchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Rchild;

              }

         }

     }

     return 0;

}

 

//   中序(根)遍历一棵二叉树,

void inorder_tree(tnode_t * root)

{

     if(root==NULL)

         return;

     else

     {

         if(root->Lchild!=NULL)

         {

              inorder_tree(root->Lchild);

         }

         printf("%d\t",root->data);

         if(root->Rchild!=NULL)

         {

              inorder_tree(root->Rchild);

         }

     }

}

 

//main函数中,输入一组无序数,调用二叉排序树插入算法,将元素放入二叉树中

int main()

{

     tree_t t;

     int x[100];

     int i=0,j=0;

     int length=0;

     int data=0;

     init_tree(&t);

    

     printf("请输入无序数的长度\n");

     scanf("%d",&length);

     printf("请输入一组无序数:\n");

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

     {

         scanf("%d",&x[i]);

         data=x[i];

         insert_BS_tree(&t,data);

     }   

     inorder_tree(t.root);

 }

Ex4_3

1.   程序流程说明:

初始化二叉树

——>

创建二叉树

——>

求深度

——>

反序

——>

中序遍历

2.程序文件名为ex4_3.cpp,源程序清单如下:

 

#include<stdio.h>

#include<stdlib.h>

//ex4-3——扩展题

//1)编写函数求一颗二叉树的深度

//2)求一颗二叉排序树的排序的反序结果,即将二叉排序树每个节点的左右子树交换,然后中序遍历之。

typedef struct tnode_t{

     int data;

     struct tnode_t * Lchild;

     struct tnode_t * Rchild;

}tnode_t;

typedef struct tree_t{

     tnode_t * root;

     int num;

}tree_t;

//初始化二叉树

 

void init_tree(tree_t *t)

{

     t->num=0;

     t->root=NULL;

}

//二叉排序树插入函数

int insert_BS_tree(tree_t * tree, int data)

{

     tnode_t *dr=(tnode_t *)malloc(sizeof(tnode_t));

     tnode_t *pr=(tnode_t *)malloc(sizeof(tnode_t));

     if(tree->root==NULL)

     {

         dr->data=data;

         dr->Lchild=NULL;

         dr->Rchild=NULL;

         tree->root=dr;

         tree->num++;

     }

     else

     {

         dr=tree->root;

         while(dr!=NULL)

         {

              if(data<dr->data)

              {

                  

                   if(dr->Lchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Lchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Lchild;

              }

              else

              {

                   if(dr->Rchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Rchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Rchild;

              }

         }

     }

     return 0;

}

int insert_BS_tree_inverse(tree_t * tree, int data)

{

     tnode_t *dr=(tnode_t *)malloc(sizeof(tnode_t));

     tnode_t *pr=(tnode_t *)malloc(sizeof(tnode_t));

     if(tree->root==NULL)

     {

         dr->data=data;

         dr->Lchild=NULL;

         dr->Rchild=NULL;

         tree->root=dr;

         tree->num++;

     }

     else

     {

         dr=tree->root;

         while(dr!=NULL)

         {

              if(data>dr->data)

              {

                  

                   if(dr->Lchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Lchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Lchild;

              }

              else

              {

                   if(dr->Rchild==NULL)

                   {

                       pr->data=data;

                       pr->Lchild=NULL;

                       pr->Rchild=NULL;

                       dr->Rchild=pr;

                       tree->num++;

                       break;

                   }

                   else

                       dr=dr->Rchild;

              }

         }

     }

     return 0;

}

int depth(tnode_t *root)

{

     int u=0;

     int v=0;

     if(root==NULL)

     return 0;

     u=depth(root->Lchild);

     v=depth(root->Rchild);

     if(u>v)

     return (u+1);

     else

     return (v+1);

 }

void inorder_tree(tnode_t * root)

{

     if(root==NULL)

     {

         return;

     }

     else

     {

         if(root->Lchild!=NULL)

         {

              inorder_tree(root->Lchild);

         }

         printf("%d\t",root->data);

         if(root->Rchild!=NULL)

         {

              inorder_tree(root->Rchild);

         }

     }

}

int main()

{

     tree_t t;

     tree_t t_inverse;

     int x[100];

     int i=0,j=0;

     int length=0;

     int data=0;

     int deepth=0;

     init_tree(&t);

     init_tree(&t_inverse);

     printf("请输入无序数的长度\n");

     scanf("%d",&length);

     printf("请输入一组无序数:\n");

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

     {

         scanf("%d",&x[i]);

         data=x[i];

         insert_BS_tree(&t,data);

     }   

     printf("\n二叉排序树中序遍历结果:\n");

    inorder_tree(t.root);

     deepth=depth(t.root);

     printf("\n二叉树的深度为%d.\n",deepth);

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

     {

         data=x[i];

         insert_BS_tree_inverse(&t_inverse,data);

     }

     printf("\n二叉排序树反序排序后的中序遍历结果:\n");

     inorder_tree(t_inverse.root);

}

1.   程序流程说明:

初始化二叉树

——>

创建哈夫曼树

——>

求出哈夫曼编码

——>

结束

  1. 程序文件名为ex4_4.cpp,源程序清单如下:

 

#include <stdio.h>

#include <stdlib.h>

static int hfmb=0;

struct tree

{

         char date;//数据

         bool min;//叶子节点

         int quanzhi;//权值

         struct tree *Lchild,*Rchild;//左右孩子

}*Tree;

struct shfm

{

         char date;//字符数据

         char bianm[16];//哈夫曼编码,最大编码数为11(可根据实际修改!)

 

}hfm[100];//哈夫曼编码对应真实数据表

 

void getTree(tree tr[],int shij,int youx)//构造哈夫曼树,tr树集合,shij集合实际数据个数,youx集合有效数据个数

{

         //模拟动态增长数组,每次构造新的树就插入有效数据后面

         if (2*youx-1!=shij)

         {

                   printf("参数不符合!");

                   return;

         }

         int c=0;

         while(youx!=shij)//当有效个数==实际个数时,构造完成!

         {

                   for (int i=c;i<youx;i++)

                   {

                            //每次循环取两个最小值并将两个最小值放置在当前循环起始两位

                            if (tr[i].quanzhi<tr[c].quanzhi)

                            {

                                     tree p=tr[i];

                                     tr[i]=tr[c];

                                     tr[c]=p;

                            }

                            if (tr[i].quanzhi<tr[c+1].quanzhi)

                            {

                                     tree p=tr[i];

                                     tr[i]=tr[c+1];

                                     tr[c+1]=p;

                            }

                   }

                   //以下为通过最小值构造的新树

                   tr[youx].quanzhi=tr[c].quanzhi+tr[c+1].quanzhi;

                 tr[youx].Rchild=&tr[c];//新树右孩子指向当前循环的最小值之一

                   tr[youx].Lchild=&tr[c+1];//新树左孩子指向当前循环的最小值之一

                   youx++;//新树插入当前有效数据个数后面 并使有效数据个数+1

                   c=c+2;

         }

}

void bianlTree(tree *tr,char ch[])//哈夫曼编码

{

         //通过遍历树,得到每个节点的编码

         static int i=0;

         if (!tr->min)//叶子节点

         {

                   ch[i]='0';

                   i++;

                   bianlTree(tr->Lchild,ch);//左节点编码为"0"

                   ch[i]='1';

                   i++;

                   bianlTree(tr->Rchild,ch);//右节点编码为"1"

         }

         if (tr->min)

         {

                   ch[i]='\0';//结束标记()

                   printf("%c    %s \n",tr->date,ch);

                   hfm[hfmb].date=tr->date;

                   int j=0;

                   while(j!=i||i>10)

                   {

                        hfm[hfmb].bianm[j]=ch[j];

                        j++;

                   }//保存编码映射表

                   hfmb++;

         }

                   i--;//递归走入右叶子节点时,取消当前赋值(当前必为左边叶子节点)

}

int main()

{

         tree tr[13]={{'a',true,115},{'b',true,11},{'c',true,14},{'d',true,35},{'e',true,516},{'f',true,254},{'g',true,55}};

//       printf("%d  \n",sizeof(tr)/sizeof(Tree));

         getTree(tr,13,7);

         char ch[100];

         //printf("%s\n",ch);

         bianlTree(&tr[12],ch);

         return 0;

}

 

  1. 程序流程说明:

1.1查找流程和程序实现说明:

顺序查找:从第一个数据元素开始,逐个把数据元素的关键字值与给定值比较,若某个元素的关键字值与给定值相等,则查找成功;否则,,若直至第n个数据元素都不相等,说明不存在满足条件的数据元素,查找失败。

二分查找:先将查找表中的数据元素按照关键字进行排序,则在查找中采用跳跃的方式——先与中间位置的数据元素的关键字进行比较,若相等,则查找成功,若给定值大于中间位置的数据元素,则在查找表的后半部进行二分查找,否则,在查找表的前半部进行二分查找。

哈希查找:

先构造哈希表

——>确定数据元素的存储地址

——>比较关键字的哈希值和地址的对照表,即可得到 。

1.2排序流程和程序实现说明:

简单选择排序:

第一趟在无序表中按照排序码选出最小的元素,将它与R1交换;第二趟排序是在无序的表中选出最小的元素,将它与R2交换,而第i趟排序时,再选出最小的元素,将它与Ri元素交换,是R1-Ri成为有序。直到整个表有序。

简单插入排序:

把n个数据元素的序列分为两部分,一个是已经排好序的有序部分,一个是未排序部分。这时,把未排序部分的一个元素一次与已经排好序的元素比较,并插入到有序部分的合适位置上,使得这些元素变为新的有序部分。

冒泡排序:

从第一个元素开始,两两比较第i和i+1元素的排序码的大小,若排序码i>i+1,则交换第i个元素和第i+1个元素的位置。第一趟全部比较完毕后第n个元素是序列最大的数据元素,如此反复,进行n-1趟冒泡排序后所有待排序的n个元素序列按排序码有序。

快速排序:

从待排序的n个元素中任意选取一个元素作为标准,调整序列中各个元素的位置,使得排在它前面的元素的排序吗都小于它的排序码,排在它后面的元素的排序码都大于它的排序码,如此反复,直到全部元素排序完毕。

  1. 源程序清单如下:

Search.cpp:

/*******************************Copyright (c)*********************************************

**                University of Electronic Science and Technology of China

**                  School of Communication and Information Engineering

**                          http://www.uestc.edu.cn

**

**--------------------------- File Info ---------------------------------------------------

** File name:           search.cpp

** Last modified Date:  2012-12-19

** Last Version:        1.0

** Descriptions:        各种检索操作,顺序表结构的定义在mystruct.h中,

**                      函数中使用的与界面显示有关接口的说明在ui.h

**                      本文件基于C语言风格

**------------------------------------------------------------------------------------------

** Created by:          Duan Jingshan

** Created date:        2012-12-19

**------------------------------------------------------------------------------------------

** Modified by:  

** Modified date:

** Version:   

** Descriptions: 

**

*******************************************************************************************/

#include "stdafx.h"

#include "mystruct.h"

#include "ui.h"

#include<string.h>

/*******************************************************************************************

** Function name: sequence_search()

** Descriptions    :    顺序检索

**                  在顺序表中找到指定元素后,将元素值取出,放置到指定内存中,可能需要使用memcpy()

** Input:

**        table_t * table; 顺序表指针

**        double stuNum;   待查询元素的关键字——学号

** Output:

**        element_t * elem; 用于存放指定元素内容的内存指针

**   return:  类型:int;待查元素在顺序表中的序号(从0开始),-1查询失败

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int sequence_search(table_t * table, double Num, element_t * elem)

{

     int i=0;

     for(i=0;i<table->length;i++)

     {

         if(table->data[i].stuID==Num)

         {

              memcpy(elem,&(table->data[i]),sizeof(element_t));

              return i;

         }

     }

     return -1;

}

 

/*******************************************************************************************

** Function name: binaray_search()

** Descriptions    :    二分检索

**                  在顺序表中找到指定元素后,将元素值取出,放置到指定内存中,可能需要使用memcpy()

** Input:

**        table_t * table; 顺序表指针

**        double stuNum;   待查询元素的关键字——学号

** Output:

**        element_t * elem; 用于存放指定元素内容的内存指针

**   return:  类型:int;待查元素在顺序表中的序号(从0开始),-1查询失败

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int binary_search(table_t * table, double Num, element_t * elem)

{

     int low=0,high=table->length-1,mid=0;

     int i=0,j=0;

     int flag=0;

//   element_t t;

//   element_t data[40];

/*   for(i=0;i<table->length;i++)

     {

         data[i].stuID=table->data[i].stuID;

     }

     for(i=0;i<table->length;i++)

     {

         for(j=i;j<table->length-1;j++)

         {

              if(table->data[j].stuID>table->data[j+1].stuID)

              {

                   t=table->data[j];

                   table->data[j]=table->data[j+1];

                   table->data[j+1]=t;

              }

         }

     }

     */

/*   for(i=0;i<table->length;i++)

     {

         if(table->data[i].stuID==Num)

         {

         //   memcpy(elem,&(table->data[i]),sizeof(element_t));

              flag=i;

         }

     }

     */

     while(low<=high)

     {

         mid=(low+high)/2;

         if(table->data[mid].stuID==Num)

         {

              memcpy(elem,&(table->data[mid]),sizeof(element_t));

              //flag=table->data[mid].stuID;

              return mid;

         }

         else if(table->data[mid].stuID<Num)

              low=mid+1;

         else

              high=mid-1;

     }

/*   for(i=0;i<table->length;i++)

     {

         if(data[i].stuID==flag)

              return i;

     }

     */

     return -1;

}

/*******************************************************************************************

** Function name: hash()

** Descriptions    :    计算关键字的哈希值,即按照设定的Hash公式计算出关键字经过Hash运算后的结果

**                  本算法设定的Hash公式仿照Daniel J.Bernstein 教授设计的DJB算法,以学生姓名

**                  的字符串为输入关键字完成计算,然后再采用截断法,将结果的最后五位(二进制)

**                  输出,即获得0~31之间的Hash结果。

**         DJB算法:

**                  设输入为a(1),a(2),……a(n)这样的字节流(字符串),

**                  hash(0) = 5381;

**                  hash(i) = (hash(i-1)*32 + hash(i-1)) + a(i)  for i = 1 to n

**                  result = hash(n) & 0x1f;

**              

** Input:

**        char * stu_name; 学生姓名字符串

** Output:

**   return:  类型:int; Hash运算结果, 0 ~ 31

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int hash(char * stu_name)

{

     int i;

     long hash = 5381;

    

     for( i = 0; i < (int)strlen(stu_name) ; i ++){

         hash = ((hash << 5) + hash) + (long)stu_name[i];

     }

     return (int)(hash & 0x1f);

}

/*******************************************************************************************

** Function name: hash_search()

** Descriptions    :    hash检索, 根据关键字计算出的hash值对hash表进行检索。

**                  hash表中,学号为0表示该位置没有填写有效的内容

**                  冲突解决方法为线性探查法

** Input:

**        table_t * table; 顺序表指针

**        char * stu_name;   待查询元素的关键字——姓名

** Output:

**        element_t * elem; 用于存放指定元素内容的内存指针

**   return:  类型:int;待查元素在顺序表中的序号(从0开始),-1查询失败

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int hash_search(table_t *table, char * stu_name, element_t * elem)

{

     int p=0,t=0,i=0;

     int a[40];

     p=hash(stu_name);

     for (i=0;i<table->length;i++)

     {

         a[i]=hash(table->data[i].stuName);

         if(a[i]==p&&strcmp(table->data[i].stuName,stu_name)==0)

         {

         memcpy(elem,&(table->data[i]),sizeof(element_t));

         return i;

         }   

     }

     //table->data[33].pinshi=0;

     //while(strcmp(table->data[p].stuName,stu_name)==1)

     //&&strcmp(table->data[p].stuName,sstu_name)==1

//   for(t=p;table->data[p].pinshi!=0;t++)

//   {

         /*if(strcmp(table->data[p].stuName,stu_name)==0)

         {

         memcpy(elem,&(table->data[p]),sizeof(element_t));

         return p;

         }*/

 

//   }

     return -1;

 

}

/*******************************************************************************************

** Function name: hash_insert()

** Descriptions    :    hash插入, 根据关键字计算出的hash值,将元素插入到hash表中。

**                  冲突解决方法为线性探查法

** Input:

**        table_t * table; 顺序表指针

**        element_t elem;   新元素

** Output:

**   return:  类型:int ; 插入结果,0表示成功,-1表示失败。

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

int hash_insert(table_t *table, element_t elem)

{

     int t=0;

     t=hash(elem.stuName);

     while(table->data[t].pinshi!=NULL)

     {

         t=(t+1)%40;

     }

     table->data[t]=elem;

     return 0;

}

 

Sort.cpp

/*******************************Copyright (c)*********************************************

**                University of Electronic Science and Technology of China

**                  School of Communication and Information Engineering

**                          http://www.uestc.edu.cn

**

**--------------------------- File Info ---------------------------------------------------

** File name:           sort.cpp

** Last modified Date:  2012-12-19

** Last Version:        1.0

** Descriptions:        各种排序操作,针对顺序表进行排序,顺序表结构的定义在mystruct.h中,

**                      函数中使用的与界面显示有关接口的说明在ui.h

**                      本文件基于C语言风格

**------------------------------------------------------------------------------------------

** Created by:          Duan Jingshan

** Created date:        2012-12-19

**------------------------------------------------------------------------------------------

** Modified by:  

** Modified date:

** Version:   

** Descriptions: 

**

*******************************************************************************************/

#include "stdafx.h"

#include "mystruct.h"

#include "ui.h"

/*******************************************************************************************

** Function name: simple_insert_sort()

** Descriptions    :    简单插入排序,按总成绩从小到大排序

**                 

** Input:

**        table_t * table; 顺序表指针

** Output:

**        table_t * table; 排序后的顺序表

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void simple_insert_sort(table_t * table)

{

     int i,j;

     element_t a;

     for(i=0;i<table->length-1;i++)

     {

         a=table->data[i+1];

         j=i;

         while(j>-1&&a.overall<table->data[j].overall)

         {

              table->data[j+1]=table->data[j];

              j--;

         }

         table->data[j+1]=a;

     }

 

}

/*******************************************************************************************

** Function name: simple_insert_sort()

** Descriptions    :    简单插入排序,按总成绩从小到大排序

**                 

** Input:

**        table_t * table; 顺序表指针

** Output:

**        table_t * table; 排序后的顺序表

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void simple_select_sort(table_t * table)

{

     int i=0;

     int j=0;

     int sma=0;

     element_t temp;

     for(i=0;i<table->length-1;i++)

     {

         sma=i;

         for(j=i+1;j<table->length;j++)

         {

              if(table->data[j].overall<table->data[sma].overall)

                   sma=j;

         }

              if(sma!=i)

              {

                   temp=table->data[i];

                   table->data[i]=table->data[sma];

                   table->data[sma]=temp;

              }

     }

    

}

/*******************************************************************************************

** Function name: simple_insert_sort()

** Descriptions    :    简单插入排序,按总成绩从小到大排序

**                 

** Input:

**        table_t * table; 顺序表指针

** Output:

**        table_t * table; 排序后的顺序表

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void bubble_sort(table_t * table)

{

     int i,j,flag;

     element_t swap;

     flag=1;

     for(i=0;i<table->length-1&&flag==1;i++)

     {

         flag=0;

         for(j=0;j<table->length-i;j++)

              if(table->data[j].overall>table->data[j+1].overall)

              {

                   flag=1;

                   swap=table->data[j];

                   table->data[j]=table->data[j+1];

                   table->data[j+1]=swap;

              }

              if(flag==0)

                   return;

     }

}

/*******************************************************************************************

** Function name: quick_sort()

** Descriptions    : 快速排序,按总成绩从小到大排序,这是一种递归算法

**                 

** Input:

**        table_t * table; 顺序表指针

**        int first; 排序范围的上边沿

**        int last; 排序范围的下边沿

** Output:

**        table_t * table; 排序后的顺序表

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void quick_sort(table_t * table,int first, int last)

{

     int i,j;

     element_t swap;

     i=first;

     j=last;

     swap=table->data[first];

     while(i<j)

     {while(i<j&&(swap.overall<=table->data[j].overall))

     j--;

     if(i<j)

     {

         table->data[i]=table->data[j];

         i++;

     }

     while(i<j&&(swap.overall>=table->data[i].overall))

         i++;

     if(i<j)

     {

         table->data[j]=table->data[i];

         j--;

     }

     }

     table->data[i]=swap;

     if(first<i)

         quick_sort(table,first,last-1);

     if(i<last)

         quick_sort(table,j+1,last);

 

}

六、实验内容:

ex5_2:Hash查找——扩展题

1)一个班有30位同学,安排装进一个有30个元素的数组,以姓名作为关键字进行哈希存储,具体方法如下:将姓名字符串中的每个字节按ASCII码(中文也支持 的哦)加起来,除以30,取得的余数作为元素存放位置(数组下标)。冲突解决采用线性探查法。

2)输入少于30个学生姓名,按Hash方式存入表中。

3)验证能够按Hash方式找到表中学生,不在表中将提示错误

ex5-4:编写快速排序函数(见实验报告:查找和排序基础)

ex5-4:归并排序——扩展题(选作)

1)两个有序的顺序表,共用1个空间,存放时两个表是连续的,即表A先存放,接着是表B,编写合并函数,合并成一个有序的顺序表,在原表上完成。

2)编写归并排序函数,先以每个元素为子表,两两归并——调用合并函数,然后继续把新表两两合并,直到最后合并成一个大表,完成归并排序

3)main函数中输入一组无序数,调用归并排序函数,进行排序,并显示排序结果。

  1. 源程序清单如下:

Ex5_2.cpp:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<math.h>

//1)一个班有30位同学,安排装进一个有30个元素的数组,以姓名作为关键字进行哈希存储,

//具体方法如下:将姓名字符串中的每个字节按ASCII码(中文也支持 的哦)加起来,除以30,取得的余数作为元素存放位置(数组下标)。冲突解决采用线性探查法。

//2)输入少于30个学生姓名,按Hash方式存入表中。

//3)验证能够按Hash方式找到表中学生,不在表中将提示错误

struct Student

{

     char a[100];

     int age;

};

 

int hash(char *cp)

{

     int sum=0,yushu;

     int n=0;

     int i=0;

     n=strlen(cp);

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

     {

         sum+=(int)*cp;

         cp++;

     }

     sum=abs(sum);

     yushu=sum%30;

     return yushu;

}

 

int hash_table(Student *student,int n)

{

     int i=0,xuh=0;

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

     {

         xuh=hash(student[i].a);

     //   printf("%d\t",xuhao);

     if(student[xuh].age!=NULL)

     {

         xuh=(xuh+1)%30;

     }

     //printf("%d",xuh);

     student[xuh]=student[i];

     }

     return 0;

}

 

int hash_search(char *name, char * stu_name,int n)

{

     int p=0,t=0,i=0;

     int a[40];

     p=hash(stu_name);

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

     {

         a[i]=hash(name);

         if(a[i]==p&&strcmp(name,stu_name)==0)

         {

         return i;

         }   

     }

     return -1;

}

 

int main()

{

     Student stu[30];

     char name[100];

     int i,j;

     int n,xuhao;

     int flag=-1;

     printf("您将输入多少个学生信息?");

     scanf("%d",&n);

     printf("\n请输入学生姓名和年龄:\n");

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

     {

         scanf("%s",&stu[i].a);

         scanf("%d",&stu[i].age);

     }

     printf("您输入的学生姓名和年龄信息如下:\n");

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

     printf("%s\t%d\n",stu[i].a,stu[i].age);

     hash_table(stu,n);

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

//   {

//       xuhao=hash(stu[i].a);

//       printf("%d\t",xuhao);

//   }

     printf("请输入需要查找的姓名:");

     scanf("%s",&name);

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

     {

         flag=hash_search(stu[i].a,name,n);

         if(flag!=-1)

         {

         printf("已找到");

         return 0;

         }   

     }

         printf("未找到");

         return -1;

}

Ex5_4:快排

/*******************************************************************************************

** Function name: quick_sort()

** Descriptions    : 快速排序,按总成绩从小到大排序,这是一种递归算法

**                 

** Input:

**        table_t * table; 顺序表指针

**        int first; 排序范围的上边沿

**        int last; 排序范围的下边沿

** Output:

**        table_t * table; 排序后的顺序表

**   return:  类型:void;

** Created by :

** Created Date    :

**------------------------------------------------------------------------------------------

** Modified by     :

** Modified Date:

**------------------------------------------------------------------------------------------

*******************************************************************************************/

void quick_sort(table_t * table,int first, int last)

{

     int i,j;

     element_t swap;

     i=first;

     j=last;

     swap=table->data[first];

     while(i<j)

     {while(i<j&&(swap.overall<=table->data[j].overall))

     j--;

     if(i<j)

     {

         table->data[i]=table->data[j];

         i++;

     }

     while(i<j&&(swap.overall>=table->data[i].overall))

         i++;

     if(i<j)

     {

         table->data[j]=table->data[i];

         j--;

     }

     }

     table->data[i]=swap;

     if(first<i)

         quick_sort(table,first,last-1);

     if(i<last)

         quick_sort(table,j+1,last);

 

}

Ex5_4选做

#include <stdio.h>

#include <stdlib.h>

//交换函数,将a,b交换

void swap(int *a,int *b){

     int temp;

     temp=*a;

     *a=*b;

     *b=temp;

}

//反序函数,将数组各元素反序排列

void reverse_array(int a[], int n) { 

    int i=0; 

    int j=n-1; 

    while (i<j) { 

        swap(&a[i], &a[j]); 

        i++; 

        j--; 

    } 

//交换函数,将数组进行一次重排。

void exchange(int a[], int length, int length_left) { 

    reverse_array(a, length_left); 

    reverse_array(a+length_left,length-length_left); 

    reverse_array(a, length); 

//归并函数 ,找出前一个大于后一个的元素,将其交换

void Merge(int a[],int begin,int mid,int end){ 

    while (begin<mid&&mid<=end){ 

        int step=0; 

        while (begin<mid&&a[begin]<=a[mid]) 

            begin++; 

        while (mid<=end&&a[mid]<=a[begin]){ 

            mid++; 

            step++; 

        } 

        exchange(a+begin,mid-begin,mid-begin-step); 

    } 

//确定两两归并的元素序号

void MergeCore(int a[], int left, int right) { 

    if (left<right){ 

        int mid = (left + right) / 2; 

        MergeCore(a, left, mid); 

        MergeCore(a, mid + 1, right); 

        Merge(a, left, mid + 1, right); 

    } 

//从第一个元素和最后一个元素开始,分——合

void MergeSort(int a[], int length) { 

    if (a == NULL || length < 1) 

        return; 

    MergeCore(a, 0, length - 1); 

}

//主函数,自定义输入,前6个为有序的,后6个为有序的,整个数组是无序的。

int main() { 

    int a[] = {1,5,9,11,16,24,2,8,14,15,21,27};

    //计算数组的长度

    int length = sizeof(a) / sizeof(int);

    MergeSort(a, length);

    for (int i = 0; i < length; i++)

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

    printf("\n");

    return 0;

}

 

posted @ 2018-03-31 15:28 Edge_of_Eternity 阅读(...) 评论(...) 编辑 收藏

数据结构算法演示(Windows版) 使 用 手 册 一、 功能简介 本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行过程中栈的变化状况。整个系统使用菜单驱动方式, 每个菜单包括若干菜单项。每个菜单项对应一个动作或一个子菜单。系统一直处于选择菜单项或执行动作状态, 直到选择了退出动作为止。 二、 系统内容 本系统内含84个算法,分属13部分内容,由主菜单显示,与《数据结构》教科书中自第2章至第11章中相对应。各部分演示算法如下: 1. 顺序表 (1)在顺序表中插入一个数据元素(ins_sqlist) (2)删除顺序表中一个数据元素(del_sqlist) (3)合并两个有序顺序表(merge_sqlist) 2. 链表 (1)创建一个单链表(Crt_LinkList) (2)在单链表中插入一个结点(Ins_LinkList) (3)删除单链表中的一个结点(Del_LinkList) (4)两个有序链表求并(Union) (5)归并两个有序链表(MergeList_L) (6)两个有序链表求交(ListIntersection_L) (7)两个有序链表求差(SubList_L) 3. 栈和队列 (1)计算阿克曼函数(AckMan) (2)栈的输出序列(Gen、Perform) (3)递归算法的演示  汉诺塔的算法(Hanoi)  解皇后问题的算法(Queen)  解迷宫的算法(Maze)  解背包问题的算法(Knap) (4)模拟银行(BankSimulation) (5)表达式求值(Exp_reduced) 4. 串的模式匹配 (1)古典算法(Index_BF) (2)求Next 函数值(Get_next)和按Next 函数值进行匹配 (Index_KMP(next)) (3)求 Next 修正值(Get_nextval)和按 Next 修正值进行匹配(Index_KMP(nextval)) 5. 稀疏矩阵 (1)矩阵转置 (Trans_Sparmat) (2)快速矩阵转置 (Fast_Transpos) (3)矩阵乘法 (Multiply_Sparmat) 6. 广义表 (1)求广义表的深度(Ls_Depth) (2)复制广义表(Ls_Copy) (3)创建广义表的存储结构(Crt_Lists) 7. 二叉树 (1)遍历二叉树  二叉树的线索化  先序遍历(Pre_order)  中序遍历(In_order)  后序遍历(Post_order) (2) 按先序建二叉树(CrtBT_PreOdr) (3) 线索二叉树  二叉树的线索化  生成先序线索(前驱或后继) (Pre_thre)  中序线索(前驱或后继) (In_thre)  后序线索(前驱或后继) (Post_thre)  遍历中序线索二叉树(Inorder_thlinked)  中序线索树的插入(ins_lchild_inthr)和删除(del_lchild_inthr)结点 (4)建赫夫曼树和求赫夫曼编码(HuffmanCoding) (5)森林转化成二叉树(Forest2BT) (6)二叉树转化成森林(BT2Forest) (7)按表达式建树(ExpTree)并求值(CalExpTreeByPostOrderTrav) 8. 图 (1)图的遍历  深度优先搜索(Travel_DFS)  广度优先搜索(Travel_BFS) (2)求有向图的强连通分量(Strong_comp) (3)有向无环图的两个算法  拓扑排序(Toposort)  关键路径(Critical_path) (4)求最小生成树  普里姆算法(Prim)  克鲁斯卡尔算法(Kruscal) (5)求关节点和重连通分量(Get_artical) (6)求最短路径  弗洛伊德算法(shortpath_Floyd)  迪杰斯特拉算法(shortpath_DIJ) 9. 存储管理 (1)边界标识法 (Boundary_tag_method) (2)伙伴系统 (Buddy_system) (3)紧缩无用单元 (Storage_compaction) 10. 静态查找 (1)顺序查找(Search_Seq) (2)折半查找 (Serch_Bin) (3)插值查找 (Search_Ins) (4)斐波那契查找 (Search_Fib) (5)次优查找树(BiTree_SOSTree) 11. 动态查找 (1)在二叉排序树上进行查找(bstsrch)、插入结点(ins_bstree)和删除结点(del_bstree) (2)在二叉平衡树上插入结点(ins_AVLtree) 和删除结点(del_AVLtree) (3)在 B-树上插入结点(Ins_BTree) 和 删除结点(Del_BTree) (4)在 B+树上插入结点(Ins_PBTree) 和 删除结点(Del_PBTree) 12. 内部排序 (1)简单排序法  直接插入排序(Insert_sort)  表插入排序(内含插入(Ins_Tsort) 重排(Arrange)两个算法)  起泡排序(BubbleSort)  简单选择排序(SelectSort) (2)复杂排序法  堆排序(HeapSort)  快速排序(QuickSort)  锦标赛排序(Tournament) (3)其他  快速地址排序(QkAddrst)  基数排序(RadixSort) 13. 外部排序 (1)多路平衡归并排序(K-Merge) (2)置换-选择排序(Repl_Selection) 三、 运行环境 1. 硬件:Pentium100以上PC机。 2. 软件:Windows95及以上版本的操作系统。 四、 运行 本系统的执行文件为DSDEMOW.EXE。 五、 如何使用本课件 读者可以利用鼠标移动光标选择“演示算法”或“菜单命令”来控制课件的运行过程。 1. 课件的演示算法菜单为页式菜单。第一级菜单中的各项与上述“系统内容”中各大项相对应,读者运行“算法演示课件”后, 即进入“算法选择一级菜单”画面,此时可移动光标进行选择,当光标所在菜单项改为红色时,单击鼠标即进入“算法选择二级菜单”,进行相同操作之后,或进入算法选择三级菜单(如图1所示),或进入算法演示的执行状态(如图2所示)。 图1 图2 在算法选择菜单画面中,形如 的图标意为尚有下级菜单,形如 的图标则表示将直接进入算法演示状态。此时也可直接单击一级菜单或二级菜单的标题直接返回之,注意:菜单右侧上方的“退出”按钮意为退出整个演示课件。 2. 算法演示执行状态下的屏幕分为三部分:第一行为“标题行”,第二行为“菜单命令”,以下为算法演示屏上各菜单的说明。 菜单命令中各项自左至右的功能分别为:  数据——设置算法演示的数据(数据结构)。  调用栈——察看当前函数(或过程)嵌套或递归的历程。  说明——察看算法说明。  暂停——中断演示过程。  执行——连续执行算法直至所设断点或至算法执行完毕。  单步——执行一行算法,遇到子程序调用时,连续执行完子程序。  跟踪——执行一行算法,遇到子程序调用时,进入子程序。  执行到——演示算法到当前所设最近的断点或算法窗口中的当前行。  恢复——重置屏幕为当前算法执行前的初始状态。  断点——在算法窗口的当前选择行设置断点或清除断点。  设置——设置连续演示时的速度或开/闭背景音乐(或动作音效)开关。  返回——返回算法选择菜单。 3. 断点的设置方法为:移动光标至“断点语句”所在行,点击鼠标后即出现绿色光条,之后单击“断点”菜单中的“设置断点”命令项即可,此时该断点语句所在行上将出现红色光条。 六、 算法演示屏的详细说明 本系统对屏幕设计的基本原则是集数据结构、算法和其他重要信息(如栈等)于同一屏幕。一般情况下演示屏由图示、算法和变量三个窗口组成,特殊情况下将根据演示内容适当增加。一般情况下, 左侧图示窗口显示演示数据的逻辑结构或存储结构,右侧上方窗口显示算法文本,右侧下方窗口显示当前算法中各变量的值或递归工作栈的状态。各窗口间的边界大小可自由调节,且可按需扩大至全屏。 算法窗口显示当前演示的算法文本,并以深蓝色的光条覆盖将要执行的语句。若算法中含有函数或过程调用语句,则当光条覆盖到该过程调用语句时,随即自动隐去原算法文本而显示子过程的文本,而从此过程返回时再重新显示原算法文本。类似地,在演示递归算法执行过程时,每当执行递归调用本过程的语句时,随即隐去当前层次的算法文本而显示下一层的算法文本,并且以不同颜色的算法文本表示递归的不同层次。如第一层的算法文本为深绿色,第二层为紫色,第三层为深红色,第四层为深蓝色,第五层为浅蓝色,第六层为玫瑰红色等。 当演示递归算法执行过程中递归工作栈的变化状态时,递归工作栈显示在右侧下窗口,递归工作栈的状态和算法文本窗口中相应语句执行后的结果相对应,栈顶记录为当前递归层的参量值。每进入一层递归时,就产生一个新的工作记录(包括调用语句行号、变量参数或全程变量、数值参数和局部变量)压入栈顶;每退出一层递归时,先根据栈顶的调用语句行号返回至上层,然后在传递完变量参数的值后退栈。 各个算法演示屏的补充说明如下: 1. 顺序表和链表的插入、删除和链表的生成 算法演示屏由显示顺序表或链表的图示、算法文本及变量等三个窗口组成。在演示算法之前,需先在弹出的小窗口中输入线性表的数据元素及算法参数 i(插入或删除的位置)和 b(被插的数据元素)的值。顺序表的图示窗口在演示屏的上方,链表的图示窗口在左侧。 2. 有序表的操作 算法演示屏的状态和 1 中所述相同。 3. 汉诺塔问题 算法演示屏由4个窗口组成。右侧上方为算法文本,在算法中有4个形式参量,其中值参 n 为圆盘个数,x、y、和 z 分别表示3个塔座;右侧下方为递归工作栈,栈中每个记录包含调用语句行号 adr 及值参 n 和 x、y、z;左侧上方显示汉诺塔图形及移动操作结果;左侧下方显示移动操作的记录。 4. 迷宫问题 左侧窗口显示迷宫的逻辑结构,由 N×N 个方格组成,左上[1,1]为入口,右下[N,N]为出口,并且以红色钉子填充表示障碍,空白表示通路,红色交通灯表示已游历过的路,箭头表示继续游历的方向,演示结束时显示一条通路或迷宫不通的信息。右侧下窗口为递归工作栈,栈中每个记录含6个数据项,其中 adr 指示调用语句行号,k 指示步数,(x,y) 表示当前坐标,i 指示路径方向(起始方向为 1,顺时针方向旋转搜索)。 5. 皇后问题 左侧图示窗口包含棋盘和递归工作栈两部分,栈中记录含3个数据项,其中 adr 指示调用语句行号,k 指示列号,i 指示行号。此算法演示可求得所有可行结果,在求得每一种排布的结果之后,会弹出一个窗口显示“找到第 j (j=1,2,…) 种排布”,单击“确定”按钮将继续进行,直至找到所有可能构成的排布。 6. 背包问题 右侧图示窗口的上方显示背包、物件及其体积。 若有解,则在求得每一组结果之后,会弹出一个窗口提示求得一组解,单击提示窗口中的小人将继续进行。该窗口的下方为递归工作栈,栈中的记录含3个数据项,其中 adr 指示调用语句所在行号,n 指示物件个数,t 指示背包总体积。 7. 阿克曼函数 整个演示屏只有显示算法文本和显示算法执行过程中栈的状态两个窗口。在执行算法之前,首先应按照提示输入参数 m 和 n 的值。 8. 栈的输出序列 图示窗口的内容为:由算法 Gen 生成的栈的操作序列(列出在窗口的下方)、算法 Perform 执行时栈的操作过程(该窗口的上方)以及算法 Perform 执行的结果——栈的输出序列(列出在图示窗口的右侧)。 9. 表达式求值 图示窗口的内容主要为显示表达式求值过程中操作数栈和运算符栈的变化情况以及主要操作。上方的小窗口显示在算法演示之前设定的表达式。 10. 离散事件模拟 图示窗口分成3部分:中间部分或显示客户流动情况的动画,或显示程序执行过程中事件表和4个队列的数值,上方两个按钮用以切换动画或静态数据,下方则显示客户总人数、客户逗留的累计时间以及调节动画中小人移动速度的指针。 11. 串的模式匹配 上窗口显示算法文本,下窗口显示串的匹配过程或求 next 函数的过程。 12. 稀疏矩阵 图示窗口显示矩阵的状态或其三元组的表示。 13. 求广义表的深度 图示窗口显示广义表的存储结构,图中指针 ls 指向当前所求深度的广义表,值为空时不显示。演示结束时弹出窗口显示求得的深度。 14. 复制广义表 图示窗口的上方显示已知广义表的存储结构,图示窗口的下方显示复制求得的广义表的存储结构。递归工作栈中含调用语句行号 adr、变参 nls 和值参 ls。 15. 创建广义表的存储结构 图示窗口显示广义表存储结构的建立过程和算法执行过程中参数Sub的当前值。 16. 遍历二叉树 图示窗口显示二叉树的逻辑结构和遍历结果输出的结点序列,图中指针 bt 指向当前遍历的二叉树的根结点。 17. 线索二叉树 图示窗口显示二叉树的存储结构,但结点中只含标志域,而以结点间的黑色连线表示指针,红色连线表示前驱线索,蓝色连线表示后继线索。在二叉树线索化的过程中,图中指针 p 指向当前层二叉树的根结点,指针 pre 指向当前被访问的结点的前驱。在演示线索树的插入和删除过程时,图示窗口的下方还包括“输入行”和“提示行”。 18. 按先序序列建二叉链表 图示窗口显示输入的先序序列和生成二叉链表的过程。 19. 森林和二叉树的相互转换 图示窗口在显示屏的上方,其左侧为森林,右侧为二叉树。 20. 赫夫曼树和赫夫曼编码 图示窗口显示生成的赫夫曼树的逻辑结构和每个叶子结点的编码。 21. 图的深度优先搜索 图示窗口的上半部分显示图的逻辑结构,初始状态用青色圆圈表示顶点,结点间的黑色连线表示边或弧(连线上画有箭头)。演示过程中用红色覆盖已访问的顶点和边(或弧)。窗口下方显示图的邻接表,演示过程中以红色框边表示已访问过的弧。图示窗口的下方显示遍历后输出的顶点序列。 22. 图的广度优先搜索 与深度优先不同的是,在窗口的下方增加一个队列,其左端为队头,右端为队尾。 23. 求有向图的强连通分量 图示窗口自上而下分别显示有向图的逻辑结构、存储结构和 Finished 数组在算法执行过程中的变化情况。所求得的各个强连通分量,将以不同颜色的顶点组表示。 24. 求关节点和重连通分量 图示窗口的上半部分显示无向图,下半部分自上而下分别显示 Vexnum、Vexdata、Visited、Low、Squlow(求得 low 值的顺序)和 artpoint(关节点)的信息。 25. 有向图的拓扑排序 图示窗口由5部分组成。其中左上显示有向图的邻接表;左下显示有向图,其中顶点和弧的初始状态分别为绿色和黑色,从栈中退出的顶点(i)用红色表示,分别以蓝色和红色指示当前访问的邻接点(k)和它们之间的弧(ik),灰白色表示已经输出的顶点;右下显示顶点的入度;右上显示入度为零的栈。当拓扑排序不成功时,在演示屏的中央将会弹出一个窗口,显示提示信息“网中存在自环!”,此时用户可在左下显示的有向图中由绿色顶点和黑色弧构成的子图中找到这个环。 26. 有向图的关键路径 图示窗口包含5部分信息。左上显示带入度域的邻接表;左下显示有向网的逻辑结构和顶点的入度及各顶点事件的最早发生时间和最迟发生时间;右下显示拓扑排序过程中入度为零的顶点的栈S,右上显示的栈 T 存放拓扑序列,其入栈顺序和栈 S 的出栈顺序相同,从栈顶到栈底的顶点顺序即为顶点的逆拓扑序列。算法执行结束后将弹出窗口列出全部结果,其中红色字体的弧表示关键活动。 27. 普里姆算法 图示窗口包含3部分内容。右上是邻接矩阵;左上是无向网的逻辑结构,图中顶点的初始状态为黄色,算法执行过程中,红色覆盖的顶点和边则表示已加入生成树的顶点和生成树上的边;窗口的下方则显示 closedge 数组中的值。 28. 克鲁斯卡尔算法 图示窗口的左侧为无向网,以红色标定已落在生成树上的边;右侧自上而下列出各条边的信息以及选择生成树的边的执行过程。 29. 边界标识法 图示窗口的初始状态为 64KB 的模拟存储器,演示过程中,以绿色覆盖占用块。各个存储块的头部左侧所示为该块的起始地址,头部结构或其他信息参见教科书。用户可根据弹出窗口的操作提示信息进行操作,输入请求分配的空间大小或释放块的首地址。 30. 伙伴系统 在图示窗口中,左侧为可利用空间链表的逻辑结构,右侧为存储结构,其中红色覆盖部分为占用块。弹出窗口为输入窗口,由用户输入请求分配的空间大小或释放块的首地址。 31. 紧缩无用单元 右侧显示存储空间,空白表示空闲块,其他颜色覆盖表示占用块,在存储空间不足分配时将进行空闲块压缩。左侧显示存储映像。弹出窗口为输入窗口,由用户输入请求分配的空间大小和分配或释放块的块名。 32. 静态查找 上窗口为图示窗口,演示查找过程;左下和右下分别为算法文本和变量窗口。 33. B-树和B+树 整个屏幕分为上、下两个窗口,上窗口演示插入或删除结点过程中B-树或B+ 树结构的变化状况;下窗口内显示如查找关键字、插入位置、结点分裂等操作信息。下窗口上面左侧的小窗口为编辑窗口,由用户输入待插或待删的关键字,输入之后其右侧的操作命令将由隐式状态改为显式状态。 34. 内部排序 图示窗口演示排序过程以及排序过程中关键字之间进行的比较次数和记录移动的次数。 七、 用户自行输入数据指南 算法操作的对象——数据结构,或由用户自行输入,或由系统随机产生,并在获得用户的确认之前,可反复随机产生,直至用户满意,用鼠标点击“OK”按钮确认为止。 多数情况下的输入界面上有足够的提示信息,以指示用户需要进行何种操作。补充说明如下: 1. 表的数据元素为任意的单个字符。 2. 迷宫的输入界面如图3所示。图中砖墙图案表示障碍,连续点击鼠标可将光标所在位置设置成通道或者障碍,建议用户先点击“随机生成”按钮随机生成一个迷宫,然后移动鼠标调整成所需。所设迷宫可以利用“保存数据”按钮生成dat类型文件,并在需要时可以利用“取出数据”按钮读入。 图3 3. 演示背包问题的算法之前,首先需要输入物品个数,之后将出现如图4所示的输入界面,可以利用“随机生成”的按钮或各个相应的小窗口输入物品体积 wi 和背包体积 T 。背包的总体积不得超过 30 ,单个物品的体积不得超过 10 。 图4 4. “表达式求值”和“建表达式树”时的输入界面如图5所示。用户可在窗口内自行输入,并以“Enter”键为结束符;也可以连续点击左侧蓝色的表达式由系统自动生成,直至用户点击右侧的计算器表示确认为止。“求值”可实现带括弧的四则运算和幂次运算,并支持sin、cos、tan、arcsin 和 arccos 等函数计算,其操作数为实数。“建树”的表达式仅限于带括弧的四则运算,其操作数为单个字母的字符。 图5 5. 稀疏矩阵的输入界面如图6所示。用户可随意进行矩阵中任意位置元素的输入,只要将光标移动至待输入的元素位置,单击鼠标后将弹出计算器,单击数字按钮,可进行随意输入,之后点击“OK”按钮表示确认。 图6 6. 广义表的数据输入方式为自左向右顺序输入广义表的字符串。输入过程中,图7所示输入界面中的“确定”为灰色字体,只有当用户正确输入完毕时,“确定”两字才改为黑色字体,此时用户可单击此按钮表示确认。 图7 7. 图的输入界面如图8所示。之前尚需确认是否为有向图和带权图。在用户自行输入图时,首先按下“创建节点”按钮,之后可移动光标至窗口的任意位置单击鼠标创建顶点;然后单击“创建弧”按钮,可在任意两个顶点之间构建弧或边。构建弧(或边)的操作为:先将光标移动至弧尾的顶点,单击一次鼠标,然后移动光标至弧头位置,再单击一次鼠标。对于带权的图,则在构建弧(或边)的同时,在当时弹出的窗口中输入权值,权值的默认值为 1。 图8 8. 内部排序的关键字为单个字符。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值