数据结构课设预习

1、问题定义

 设计一款赛事管理系统,实现赛务相关的数据管理及信息服务

(1)能够管理各参赛队的基本信息

(2)根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息

(3)根据赛事类别查询参赛团队,若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。

(4)设计叫号系统,所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号(5)为参赛者提供各种路径导航的查询服务。

2、问题分析

(1)根据线性表的增、删、改、查对各参赛对的信息进行管理,对于线性表的删除,在初始化时,我们首先初始化线性表的大小和长度并以此大小申请内存数组空间,删除时,直接释放对应的数组空间以及Vector结构体空间。

(2)从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。二叉排序树又称为二叉查找树,它是一种特殊的二叉树。二叉排序树是一颗空树或者是具有一下性质的二叉树
(3)对输出的参赛团队按赛事类别有序输出,能够选择多种排序方式,插入排序时间复杂度:最坏情况下为O(N*N),此时待排序列为逆序,或者说接近逆序。最好情况下为O(N),此时待排序列为升序,或者说接近升序,空间复杂度:O(1)。希尔排序先将待排序列进行预排序,使待排序列接近有序,然后再对该序列进行一次插入排序,此时插入排序的时间复杂度为O(N),其时间复杂度平均:O(N^1.3)空间复杂度:O(1)。选择排序每次从待排序列中选出一个最小值,然后放在序列的起始位置,直到全部待排数据排完即可。实际上,我们可以一趟选出两个值,一个最大值一个最小值,然后将其放在序列开头和末尾,这样可以使选择排序的效率快一倍。冒泡排序则是左边大于右边交换一趟排下来最大的在右边。

(4)要求模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况,可以运用栈和队列的知识。采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶元素的位置。若存储栈的长度为StackSize,则栈顶位置top必须小于StackSize。当栈存在一个元素时,top等于0,因此通常把空栈的判断条件定位top等于-1。采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。通常采用单链表实现,并规定所有操作都是在单链表的表头进行的。这里规定链栈没有头节点,Lhead指向栈顶元素。

(5)任务中要求求解出图中景点的问路查询,即为给定两个源点,求解出两个顶点之间的最短路径。根据数据结构课程所学知识,有多种经典算法可以解决最短路径问题,包括 Dijkstra算法,Floyd-Warshell 算法,Bellman-Ford 算法和深度优先遍历。不同是算法有不同的算法复杂度,考虑到校园中道路没有负权边,即算法均可解决最短路径问题。

    其中 Dijkstra 算法求的是单源最短路径:即从一个结点出发到其它所有结点的最短路径,算法的时间复杂度为 O(n 2 ),但题目要求任意两个结点的最短路径,所以还是要在外层增加一个循环,以求得多源最短路径。

    而 Floyd 算法求的是多源最短路径:即从任意结点出发到其它所有结点的最短路径,算法的时间复杂度为 O(n 3 ) ,它可以一次性求得所有结点间的最短路径,且算法思想简单,便于理解。所以我们这一项目采用 Floyd 算法来求解最短路径。
    针对这一项目,我们可以为其增加一个功能:求从指定结点开始,不重复的游览其它所有景点一次的推荐路径:即一条哈密尔顿路径。这一问题可以采用基于深度优先搜索 DFS的马踏棋盘算法进行解决,并且可以利用贪心思想对这一算法进行优化。
    这显然是一个图论问题,而且校园内道路一般是双向通行的,所以这是一个无向图。对于图的存储结构而言,图中各个景点的存储结构有邻接表和邻接矩阵两种存储结构,考虑到顶点个数少于 50 个,所以邻接表和邻接矩阵的复杂度相同。本题中选择使用邻接矩阵来表示图。

3、概要设计

(1)根据线性表的增、删、改、查对各参赛对的信息进行管理,对于线性表的删除,在初始化时,我们首先初始化线性表的大小和长度并以此大小申请内存数组空间,删除时,直接释放对应的数组空间以及Vector结构体空间。

//插入数据

    public void insert(int i, T x) {

        if (x == null)

            return;

        // 若数组满,则扩充顺序表容量

        if (this.len == element.length) {

            // temp也引用elements数组

            Object[] temp = this.element;

            // 重新申请一个容量更大的数组

            this.element = new Object[temp.length * 2];

            // 复制数组元素,O(n)

            for (int j = 0; j < temp.length; j++) {

                this.element[j] = temp[j];

            }

        }

        // 下标容错

        if (i < 0)

            i = 0;

        if (i > this.len)

            i = this.len;

        // 元素后移,平均移动len/2

        for (int j = this.len - 1; j >= i; j--) {

            this.element[j + 1] = this.element[j];

        }

        this.element[i] = x;

        this.len++;

    }

//在顺序表最后插入x元素

    public void append(T x) {

        insert(this.len, x);

    }

//删除

    public T remove(int i) {

        if (this.len == 0 || i < 0 || i >= this.len) {

            return null;

        }

        T old = (T) this.element[i];

        // 元素前移,平均移动len/2

        for (int j = i; j < this.len - 1; j++) {

            this.element[j] = this.element[j + 1];

        }

        this.element[this.len - 1] = null;

        this.len--;

        return old;

    }

   // 删除线性表所有元素

    public void removeAll() {

        this.len = 0;

    }

(2)实现基于二叉排序树的查找。

typedef struct BSTNode{

    int key;

    struct BSTNode *lchild, *rchild;

}BSTNode, *BSTree;

//在二叉排序树中查找值为key的结点

BSTNode *BST_Search(BSTree_T, int key){

    while(T!=NULL && key!=T->key){           //若树空或等于根结点值,则结束循环

        if(key < T->key)

            T = T->lchild;                   //小于,则在左子树上查找

        else

            T = T->rchild;                   //大于,则在右子树上查找

    }

    return T;

}

(3)实现对对输出的参赛团队按赛事类别有序输出,能够选择多种排序方式,

public class demo_sort {

    public static void main(String[] args) {

        //冒泡排序算法

        int[] numbers=new int[]{1,5,8,2,3,9,4};

        //需进行length-1次冒泡

        for(int i=0;i<numbers.length-1;i++)

        {

            for(int j=0;j<numbers.length-1-i;j++)

            {

                if(numbers[j]>numbers[j+1])

                {

                    int temp=numbers[j];

                    numbers[j]=numbers[j+1];

                    numbers[j+1]=temp;

                }

            }

        }

        System.out.println("从小到大排序后的结果是:");

        for(int i=0;i<numbers.length;i++)

            System.out.print(numbers[i]+" ");

    }

}

(4)要求模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况,可以运用栈和队列的知识。

//顺序队列 头文件 SeqQueue.h

#ifndef _SEQQUEUE_H_

#define _SEQQUEUE_H_

typedef void SeqQueue;

SeqQueue *SeqQueue_Create(int capacity);

void SeqQueue_Destroy(SeqQueue *queue);

void SeqQueue_Clear(SeqQueue *queue);

int SeqQueue_Append(SeqQueue *queue, void *item); //加入队列

void *SeqQueue_Retrieve(SeqQueue *queue);         //出队列

void *SeqQueue_Header(SeqQueue *queue);           //获取头部

int SeqQueue_Length(SeqQueue *queue);

int SeqQueue_Capacity(SeqQueue *queue);

#endif

//顺序队列 源文件 SeqQueue.c

#include "SeqList.h"

#include "SeqQueue.h"

SeqQueue *SeqQueue_Create(int capacity) // O(1)

{

    return SeqList_Create(capacity);

}

void SeqQueue_Destroy(SeqQueue *queue) // O(1)

{

    SeqList_Destroy(queue);

}

void SeqQueue_Clear(SeqQueue *queue) // O(1)

{

    SeqList_Clear(queue);

}

int SeqQueue_Append(SeqQueue *queue, void *item) // O(1)加入队列

{

    return SeqList_Insert(queue, item, SeqList_Length(queue));

}

void *SeqQueue_Retrieve(SeqQueue *queue) // O(n) 出队列

{

    return SeqList_Delete(queue, 0);

}

void *SeqQueue_Header(SeqQueue *queue) // O(1) 获取头部元素

{

    return SeqList_Get(queue, 0);

}

int SeqQueue_Length(SeqQueue *queue) // O(1)

{

    return SeqList_Length(queue);

}

int SeqQueue_Capacity(SeqQueue *queue) // O(1)

{

    return SeqList_Capacity(queue);

}

(5)不同是算法有不同的算法复杂度,考虑到校园中道路没有负权边,即算法均可解决最短路径问题。

结点信息的数据结构:类——View 用于存储各个结点的详细信息,如景点编号、名称

和景点介绍,该类还提供了相应的 setter 和 getter。

public class View {

//景点的编号

private int id;//景点的名称

private String name;

//景点的介绍

private String introduction;

//构造方法

public View(int id, String name, String introduction) {

this.id = id;

this.name = name;

this.introduction = introduction;

}

}

下面是图的数据结构:前面提到过本题采用邻接矩阵来存储图,并且是无向图的存储格

式。提供了图结构最大结点数为 20:即最多扩展 20 个结点,原图选取了 12 个结点作为校

内景点。顶点数组采用了 View 类型的数组以便于信息的查询,因为要使用到 Floyd 算法,

所以还有图的前趋结点数组(路径数组),另外该类还提供了相应的 getter 和 setter 并在构造

方法中初始化了图的各种信息。

public class MGraph {

//最大顶点数

public static final int MAX_SIZE = 20;

//最大权值,即∞

public static final int MAX_INT = 65535;

//顶点数组

private View[] vertex = new View[MAX_SIZE];

//图的邻接矩阵

private int[][] adj = new int[MAX_SIZE][MAX_SIZE];

//图的前趋结点数组

private int[][] pre = new int[MAX_SIZE][MAX_SIZE];

//图的顶点数和边数

private int vertexNum, edgeNum;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值