数据结构期末考题

1.头插法创建学生数据类型单链表

#include <stdio.h>
#include<stdlib.h>
#include<string.h>

/* 定义学生数据类型STUDENT */
typedef struct date
{  
	int year;
    int month;
    int day;
}DATE;
typedef struct student
{
     int num;
     char name[20];
     char sex;
     DATE birthday;
     float score;
}STUDENT;

/* 定义ElemType为STUDENT类型 */
typedef STUDENT ElemType;

void input(ElemType &s);
void output(ElemType s);

/* 单链表类型定义 */
typedef struct LNnode
{	
	ElemType data;
	struct LNnode *next;
}LNnode,*LinkList;
void CreateHeadList(LinkList  &L, ElemType  a[ ], int n ) ; //根据数组用头插法创建单链表 
void ListTraverse(LinkList L,void(*vi)(ElemType));

int  main()
{
    LinkList  head;          //定义一个LinkList 型的变量head
    head = (LNnode*)malloc(sizeof(LNnode));
    head -> next = NULL;
    ElemType  a[100 ];
    int n,i;
    scanf("%d",&n);
    for(i=0; i<n; i++ )                //遍历a数组所有元素
    {
        input(a[i]);
    }
    CreateHeadList (head,a,n);     //用头插法输入数据创建单链表
    ListTraverse (head,output);         //输出以head为头的链表各结点的值  
    return 0; 
}
void input(ElemType &s)
{
    //printf("请输入学生学号:");
    scanf("%d",&(s.num));
    //printf("请输入学生姓名:");
    scanf("%s", s.name);
    //printf("请输入学生性别:");
    scanf(" %c",&(s . sex));
    //printf("请输入学生出生日期:");
    scanf("%d%d%d",&s.birthday.year, &s.birthday.month, &s. birthday.day);
    //printf("请输入学生成绩:");
    scanf("%f",&(s.score));	
}

void output(ElemType s)
{
  printf("学号:%d\t姓名:%s\t性别:%c\t", s.num,s.name,s.sex);
  printf("出生日期:%d-%d-%d\t", s.birthday.year,s.birthday.month, s.birthday.day);
  printf("成绩:%.1f\n", s.score);
}


void ListTraverse(LinkList L,void(*vi)(ElemType))
{ 
	// 初始条件:单链表L已存在。
	//操作结果:依次对L的每个数据元素调用函数vi()
    /********** Begin **********/
    LinkList p = L -> next; 
    while(p){
        vi(p -> data);
        p  = p -> next;
    }
    printf("\n");
    /********** End **********/
	
}
void CreateHeadList(LinkList  &L, ElemType  a[], int n )  
{
    //根据长度为n的数组a用头插法来创建单链表L
    /********** Begin **********/
    int i;
    LNnode *p;
    for(i = 0; i < n; i++){
        p = (LNnode*)malloc(sizeof(LNnode));
        p -> data = a[i];
        p -> next = L -> next;
        L -> next = p;
    }
    /********** End **********/
} 

2.打印和遍历二叉树

 1.打印二叉树

#include "tree.h"
#include <stdio.h>
#include <stdlib.h>
#include<bits/stdc++.h>
//创建二叉树
char *x;
void CreateBTree(BTNode *&b,char *str)
{
    BTNode *St[MaxSize],*p;//St数组作为顺序栈
    int top=-1,k,j=0;//top作为栈顶指针
    char ch;
    b=NULL;//初始时二叉链为空
    ch=str[j];
    while(ch!='\0')
    {
        switch (ch)
        {
            case '(':top++;St[top]=p;k=1;break; //处理左孩子
            case ')':top--;break;               //栈顶的子树处理完毕
            case ',':k=2;break;                 //开始处理右孩子
            default:
                p=(BTNode*)malloc(sizeof(BTNode));  //创建一个结点由p指向它
                p->data=ch;                         //存放结点值
                p->lchild=p->rchild=NULL;           //左右指针都置为空
                if(b==NULL)                         //若尚未建立根结点
                {
                    b=p;                            //b所指结点作为根结点
                }
                else                                //已建立二叉树根结点
                {
                    switch(k)
                    {
                        case 1:St[top]->lchild=p;break;     //新建结点作为栈顶左孩子
                        case 2:St[top]->rchild=p;break;     //新建结点作为栈顶右孩子
                    }
                }
        }
        j++;                                                //继续扫描str
        ch=str[j];
    }
    x = str;
}
//销毁树
void DestroyBTree(BTNode *&b)
{
    if(b!=NULL)
    {
        DestroyBTree(b->lchild);
        DestroyBTree(b->rchild);
        free(b);
    }
}
//输出树

void DispBTree(BTNode *b)
{
    /********** Begin **********/
/*    if(b != NULL){
        printf("%c", b -> data);
        if(b -> lchild != NULL || b -> rchild != NULL){
            printf("(");
            DispBTree(b -> lchild);
            if(!b -> rchild){
                printf(",");
            }
            DispBTree(b -> rchild);
            printf(")");
        }
    }*/
    for(int i = 0; i < strlen(x); i++){
        printf("%c", x[i]);
    }
    /********** End **********/    
}

2.遍历二叉树

#include "tree.h"
#include <stdio.h>
#include <stdlib.h>
//先序遍历
void PreOrder(BTNode *b)
{
    /********** Begin **********/
    if(b == NULL)  return;
    printf("%c", b -> data);
    PreOrder(b -> lchild);
    PreOrder(b -> rchild);
    /********** End**********/
}
//中序遍历
void InOrder(BTNode *b)
{
    /********** Begin **********/
    if(b == NULL)  return;
    InOrder(b -> lchild);
    printf("%c", b -> data);
    InOrder(b -> rchild);
    /********** End **********/
}
//后续遍历
void PostOrder(BTNode *b)
{
    /********** Begin **********/
    if(b == NULL)  return;
    PostOrder(b -> lchild);
    PostOrder(b -> rchild);
    printf("%c", b -> data);
    /********** End **********/
}

3.图的深度优先遍历

#include "graph.h"
#include <stdio.h>
#include <stdlib.h>
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)  //创建图的邻接表
{
    int i,j;
    ArcNode *p;
    G=(AdjGraph *)malloc(sizeof(AdjGraph));
    for(i=0;i<n;i++)                                        //给邻接表的头元素的指针域置初值
    {
        G->adjlist[i].firstarc=NULL;
    }
    for(i=0;i<n;i++)                                        //检查邻接表的每个元素
    {
        for(j=n-1;j>=0;j--)
        {
            if(A[i][j]!=0&&A[i][j]!=INF)                    //存在一条边
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));       //创建一个结点p
                p->adjvex=j;                                //存放邻接点
                p->weight=A[i][j];                          //存放权
                p->nextarc=G->adjlist[i].firstarc;          //采用头插法插入结点p
                G->adjlist[i].firstarc=p;
            }
        }
    }
    G->n=n;
    G->e=e;
}
void DispAdj(AdjGraph *G)
{
    int i;
    ArcNode *p;
    for(i=0;i<G->n;i++)
    {
        p=G->adjlist[i].firstarc;
        printf("%3d: ",i);
        while(p!=NULL)
        {
            printf("%d[%d]→",p->adjvex,p->weight);
            p=p->nextarc;
        }
        printf("^\n");
    }
}
void DestroyAdj(AdjGraph *&G)
{
    int i;
    ArcNode *pre,*p;
    for(i=0;i<G->n;i++)                 //扫描所有单链表
    {
        pre=G->adjlist[i].firstarc;     //p指向第i个单链表的头结点
        if(pre!=NULL)
        {
            p=pre->nextarc;
            while(p!=NULL)              //释放第i个单链表的所有结点
            {
                free(pre);
                pre=p;
                p=p->nextarc;
            }
            free(pre);
        }
    }
    free(G);
}
//深度优先遍历
int visited[MAXV];                //全局数组,记录访问的点
void DFS(AdjGraph *G,int v)
{
    /********** Begin **********/
    visited[v] = 1;
    printf("%d  ", v);
    ANode *p = G -> adjlist[v].firstarc;
    while(p){
        if(!visited[p -> adjvex]){
            DFS(G, p -> adjvex);
            p = p -> nextarc;
        }
       else{
           p = p -> nextarc;
           continue;
       }
    }
    /********** End **********/
}

4.最小生成树

1.prim

#include "graph.h"  
  
void Prim(MGraph g,int v)  
{  
    int lowcost[MAXV];          //顶点i是否在U中  
    int min;  
    int closest[MAXV],i,j,k;  
    for (i=0; i<g.n; i++)           //给lowcost[]和closest[]置初值  
    {  
        lowcost[i]=g.edges[v][i];  
        closest[i]=v;  
    }  
    for (i=1; i<g.n; i++)           //找出n-1个顶点  
    {  
        min=INF;  
        for (j=0; j<g.n; j++)     //在(V-U)中找出离U最近的顶点k  
            if (lowcost[j]!=0 && lowcost[j]<min)  
            {  
                min=lowcost[j];  
                k=j;            //k记录最近顶点的编号  
            }  
        printf(" 边(%d,%d)权为:%d\n",closest[k],k,min);  
        lowcost[k]=0;           //标记k已经加入U  
        for (j=0; j<g.n; j++)       //修改数组lowcost和closest  
            if (g.edges[k][j]!=0 && g.edges[k][j]<lowcost[j])  
            {  
                lowcost[j]=g.edges[k][j];  
                closest[j]=k;  
            }  
    }  
}  
  
int main()  
{  
    MGraph g;  
    int A[6][6]=  
    {  
        {0,10,INF,INF,19,21},  
        {10,0,5,6,INF,11},  
        {INF,5,0,6,INF,INF},  
        {INF,6,6,0,18,14},  
        {19,INF,INF,18,0,33},  
        {21,11,INF,14,33,0}  
    };  
    ArrayToMat(A[0], 6, g);  
    printf("最小生成树构成:\n");  
    Prim(g,0);  
    return 0;  
}  

2.krusal

typedef pair<int,int> PII;
const int N = 2e5+7;

struct node{
    int x,y,z;
    bool operator<(node &t)const{
        return z < t.z;
    }
}edge[N];

int fa[N],n,m,ans;

int Find(int x){
    if(x == fa[x])return x;
    return fa[x] = Find(fa[x]);
}

int main()
{
    cin>>n>>m;
    over(i,1,m)
    scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);
    sort(edge + 1,edge + 1 + m);
    over(i,1,n)
    fa[i] = i;
    over(i,1,m){
        int x = Find(edge[i].x);
        int y = Find(edge[i].y);
        if(x == y)continue;
        fa[x] = y;
        ans += edge[i].z;
    }
    printf("%d\n",ans);
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值