数据结构课堂实验合集

目录

顺序表逆置

单链表逆置 

火车的调度

进制转化

二叉树

图的深度遍历

查找的实现

内部排序的实现


顺序表逆置

编写程序实现:

        1、在原来的顺序表中将顺序表实现逆置。

        2、要求顺序表的内容由用户输入,并分别显示出逆置前和逆置后的顺序表。

定义顺序表的结构体,并对顺序表进行初始化,用malloc 函数申请一片连续的存储空间,增加动态数组的长度,实行动态分配。当n为奇数,将第一个元素与最后一个元素进行交换,第二个与倒数第二个进行交换,以此类推,最中间的元素无需交换;n为偶数,也是将第一个元素与最后一个元素进行交换,第二个与倒数第二个进行交换,以此类推,但最中间两个元素要进行交换。

#include<stdio.h>
#include<stdlib.h>
#define InitSize 100

typedef struct{
    int *data;
    int Maxsize;
    int length;
}SeqList;

void InitList(SeqList &L){
    L.data=(int*)malloc(InitSize*sizeof(int));
    L.length=0;
    L.Maxsize=InitSize;
}

void IncreateSize(SeqList &L,int len){
    int *p=L.data;
    L.data =(int*)malloc((L.Maxsize+len)*sizeof(int));
    for(int i=0;i<L.length;i++){
        L.data[i]=p[i];
    }
    L.Maxsize=L.Maxsize+len;
    free(p);
}

void CreatList(SeqList &L, int length){
    printf("输入元素值:\n");
    for (int i=0;i<length;i++) {
        scanf("%d", L.data + i);
        L.length = length;
    }
}

void PrintList(SeqList &L){
    int i=0;
    for(;i<L.length;i++){
        printf("%d ",L.data[i]);
    }
}

void TransList(SeqList &L){
    int i,temp;
    for(i=0;i<L.length/2;i++){
        temp=L.data[i];
        L.data[i]=L.data[L.length-1-i];
        L.data[L.length-1-i]=temp;
    }
}

int main(){
    int length;
    SeqList L;
    InitList(L);
    printf("输入多少个元素?\n");
    scanf("%d",&length);
    IncreateSize(L,length);
    CreatList(L,length);
    printf("逆置后的结果为:\n");
    TransList(L);
    PrintList(L);
}

单链表逆置 

编写程序实现:

        1、在原有的单链表中,将单链表实现逆置。(即不增加新的结点)

        2、程序要求单链表的内容由用户输入,并分别显示出逆置前和逆置后的单链表。

定义单链表,申请新的空间head指针指向链表首地址,建立链表,并接收链表首地址,将首地址传递给链表输出函数,输出链表。单链表逆置将最后一个提到最前面,倒数第二个放到第二个,以此类推,直到第一个到最后一个。

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

struct node{
    int data;
    struct node *next;
};

node *Creat(){
    node *head=(node*)malloc(sizeof(node));
    node *p=head;
    int N;
    printf("输入多少个元素?\n");
    scanf("%d",&N);
    printf("输入元素值:\n");
    if(N<=0) return NULL;
    for(int i=0;i<N;i++){
        node *q=(node*)malloc(sizeof(node));
        scanf("%d",&(q->data));
        q->next=NULL;
        p->next=q;
        p=p->next;
    }
    return head;
}

node *Reverse(node *head){
    node *p=NULL;
    node *next=NULL;
    p=head->next;
    next=head->next->next;
    while(next!=NULL){
        p->next=next->next;
        next->next=head->next;
        head->next=next;
        next=p->next;
    }
    return head;
}

void Output(node *head){
    node *p=(node*)malloc(sizeof(node));
    p=head;
    printf("逆置后的结果为:\n");
    while((p=p->next)){
        printf("%d ",p->data);
    }
    free(p);
    printf("\n");
}

void Free(node *head)
{
    if (head->next==NULL) return;
    node *p=head;
    while((p=p->next)){
        head->next=p->next;
        free(p);
        p=head;
    }
    free(head);
}

int main(void){
    node *head=Creat();
    Reverse(head);
    Output(head);
    Free(head);
}

火车的调度

编写程序实现:

        利用栈解决火车调度问题,将本来杂乱无章的车厢排成 软席(S)在前,硬席(H)在后。车厢序列通过键盘输入,如HSHSHSSSH,输出SSSSSHHHH。

挨个读取字符串,若遇到硬座,将其入栈,若是软座,先入栈后立刻出栈,最后,读取完毕时所有硬座都还在栈内,依次出栈直到栈为空。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MaxSize 100

struct Stack{
	char stack[MaxSize];
	size_t size;
};

void init(Stack *p){
	p->size=0;
}

void push(Stack *p,char ch){
	p->stack[p->size++]=ch;
}

bool pop(Stack *p){
	if(p->size == 0) return false;
	else{
		--p->size;
		return true;
	}
}

bool top(Stack *p,char *ch){
	if(p->size == 0) return false;	
	else{
		*ch=p->stack[p->size-1];
		return true;
	}
}

bool empty(Stack *p){
	return p->size == 0;
}

void diaodu(){
	Stack s;
	char ch,input[MaxSize];
	init(&s);
	fgets(input,MaxSize,stdin);
	input[strlen(input)-1]=0;
	printf("????????????");
	for(size_t i=0;i<strlen(input);++i){
		push(&s,input[i]);
		if(top(&s,&ch) && ch=='S'){
			pop(&s);
			printf("%c",ch);
		}
	}
	while(!empty(&s)){
		top(&s,&ch);
		pop(&s);
		printf("%c",ch);
	}	
}

int main(){
	printf("软席车厢用“S”表示、硬席车厢用“H”表示\n");
	printf("请输入车厢序列:");
	diaodu();
}

进制转化

编写程序实现:

        进制之间的转换:如 将10进制转换为d进制,10进制数n和要转换的进制d通过键盘输入。

由N=(N div d)×d+N mod d得余数,将其从低位到高位获得的数即为转换所求的数,这个原理和栈的先进后出相同,若将计算

过程中得到的数的各位顺序进栈,则按出栈序列输出的就时对应的进制转换后所得的数。

#include<stdlib.h>
#include<stdio.h>
#include<stddef.h>
#define MAXSIZE 100 
 
typedef struct 
{ char data[MAXSIZE];
  int top;
}sqstack,*psqstack;

psqstack Initstack(){
	psqstack s;
	s=(psqstack)malloc(sizeof(sqstack));
	if(s) s->top=-1;
	return s;	
}

int Emptystack(psqstack s){
	if(s->top==-1) return 1;
	else return 0;
}

int Push(psqstack s,char x){
	if(s->top==MAXSIZE-1) return 0;
	else{
		s->top=s->top+1;
       s->data[s->top]=x;
       return 1;
    }
}

int Pop(psqstack s,char *x){
	if(Emptystack(s)) return 0;
	else{
		*x=s->data[s->top];
    	s->top=s->top-1;
    	return 1;
  	}
}
int GetTopstack(psqstack s,char *x){
	if(Emptystack(s)) return 0;
	else *x=s->data[s->top];
    return 1;
}

void Destroystack(psqstack *s){
	if(*s)
 	free(*s);
	*s=NULL;
	return;     
}
 
void Conversion(int num,int r){
	psqstack s;
	char x;
	if(!r){
		printf("基数不能为0");
    	return;
    }
	s=Initstack();
	if(!s){
		printf("初始化栈空间失败");
		return; 
    }
    
	while(num){
	if(num%r>9)
    	Push(s,num%r+'A'-10);
   else
    	Push(s,num%r+'0');
   num=num/r;
   }
	while(!Emptystack(s)){
		Pop(s,&x);
		printf("%c",x);
	}
}

int main(){
	int r, num;
	printf("请输入要转换的数据");
	scanf("%d",&num);
	printf("请输入要转换成几进制:");
	scanf("%d",&r);
	Conversion(num,r); 
}

二叉树

编写程序实现:

        1、采用递归先序算法建立二叉树,要求通过键盘输入二叉树的先序遍历顺序从而建立一棵二叉树。

        2、利用栈实现一棵二叉树的非递归遍历。

        3、要求显示遍历次序。

用递归先序算法建立二叉树,输入需要将二叉树补成满二叉树,用空格表示空结点,当遇到“ ”时,令该结点为NULL,结束此分支。递归后序遍历输出先判断非空二叉树后递归遍历左子树,再递归遍历右子树,最后访问根结点,递归先序遍历、递归中序遍历同理。非递归先序遍历,先设置一个栈,判断二叉树是否为空,若为空退出,否则第一次访问的根结点入栈并输出,若有左孩子,将其入栈并输出,若无,取出栈顶结点,若有右子树,重复上述步骤,若无,继续取出栈顶结点,直到结点空、栈空。非递归中序遍历,先将根结点入栈,若有左子树,取出栈顶结点并输出,若有右子树将当前结点入栈,,否则继续取出栈顶结点并输出。

#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW (-2)

typedef char TreeData;
typedef struct node{
    TreeData data;
    struct node *lchild,*rchild;
}BinTreeNode,*BiTree;

void CreateBiTree(BiTree &T){
    TreeData ch=getchar();
    if(ch==' ') T=NULL;
    else{
        if (!(T=(BinTreeNode*)malloc(sizeof(node))))
            exit(OVERFLOW);
        T->data=ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}
//递归先序
void DLR(BinTreeNode *BiTree){
    if(BiTree != NULL){
        printf("%c",BiTree->data);
        DLR(BiTree->lchild);
        DLR(BiTree->rchild);
    }
}
//递归中序
void LDR(BinTreeNode *BiTree){
    if(BiTree != NULL){
        DLR(BiTree->lchild);
        printf("%c",BiTree->data);
        DLR(BiTree->rchild);
    }
}
//递归后序
void LRD(BinTreeNode *BiTree){
    if(BiTree != NULL){
        DLR(BiTree->lchild);
        DLR(BiTree->rchild);
        printf("%c",BiTree->data);
    }
}
//非递归先序
void PreOrderTraverse(BinTreeNode *BiTree){
    BinTreeNode *T=BiTree,*s[100];
    int top=0;
    while(T||top>0){
        if(T){
            printf("%c",T->data);
            s[top++]=T;
            T=T->lchild;
        }else{
            T=s[--top];
            T=T->rchild;
        }
    }
}
//非递归中序
void InOrderTraverse(BinTreeNode *BiTree){
    BinTreeNode *T=BiTree,*s[100];
    int top=0;
    while(T||top>0){
        if(T){
            s[top++]=T;
            T=T->lchild;
        }else{
            T=s[--top];
            printf("%c",T->data);
            T=T->rchild;
        }
    }
}

int main (){
    BiTree T;
    printf("请按先序顺序输入二叉树,用空格表示空结点:\n");
    CreateBiTree(T);
    printf("先序输出:");
    DLR(T);
    printf("\n中序输出:");
    LDR(T);
    printf("\n后序输出:");
    LRD(T);
    printf("\n非递归先序输出:");
    PreOrderTraverse(T);
    printf("\n非递归中序输出:");
    InOrderTraverse(T);
}

图的深度遍历

编写程序实现:

        1、实现图的创建。

        2、要求显示深度优先遍历次序。

从顶点出发:访问顶点;依次从该顶点的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和该顶点有路径相通的顶点都被访问;若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。

#include <stdio.h>
#define MAX_VERTEX_NUM 20

typedef char VertexType;
typedef struct{//图的定义
    VertexType vexs[MAX_VERTEX_NUM ];//顶点表,用一维向量即可, VertexType: char/int
    VertexType arcs[MAX_VERTEX_NUM ][MAX_VERTEX_NUM ]; //邻接矩阵
    int vexnum,arcnum;   //顶点总数,弧(边)总数
}Mgraph;

int LocateVex(Mgraph G,VertexType u){ 
    int i;
    for(i=0;i<G.vexnum;++i){
        if(u==G.vexs[i]){
            return i;
        }
    }
    return -1;
}

void CreateUDN(Mgraph &G){//无向网的构造,用邻接矩阵表示
    int i, k, j;
    char v1, v2;
    printf("输入顶点个数和边数:\n");
    printf("顶点数:");
    scanf("%d",&G.vexnum);
    printf("边数:");
    scanf("%d",&G.arcnum);//输入总顶点数,总弧数和信息
    printf("输入顶点元素:");
    for(i=0;i<G.vexnum;++i){
        getchar();//防止读入回车键
        scanf("%c",&G.vexs[i]);//输入顶点值,存入一维向量中
    }
    for(i=0; i<G.vexnum; ++i) {//对邻接矩阵n*n个单元初始化
        for(j=0;j<G.vexnum;++j){
            G.arcs[i][j]= 0;
        }
    }
    int w;//权值
    printf("请输入边的信息:\n");
    for(k=0;k<G.arcnum;++k){//给邻接矩阵有关单元赋初值(循环次数=弧数
        getchar();
        printf("输入弧的两顶点以及对应权值:");
        scanf("%c,%c,%d",&v1,&v2,&w); //输入弧的两顶点以及对应权值, 或者scanf(&v1, &v2)
        i=LocateVex(G,v1);
        j=LocateVex(G,v2); //找到两顶点在矩阵中的位置(n次)
        G.arcs[i][j]=w;
        G.arcs[j][i] = G.arcs[i][j]; //无向网是对称矩阵
    }
}

int visited[MAX_VERTEX_NUM];

void DFS(Mgraph G,int v){
    int w;//访问第v个顶点
    printf("%c",G.vexs[v]);
    visited[v] = 1;
    for(w = 0; w< G.vexnum; w++){//依次检查邻接矩阵v所在的行
        if((G.arcs[v][w]!=0)&& (!visited[w])){
            DFS(G,w);
        }
    }
}

void DFSTraverse(Mgraph G){//对图 G作深度优先遍历。
    int v;
    for (v=0; v<G.vexnum; ++v) visited[v] = 0; //访问标志数组初始化
    for (v=0; v<G.vexnum; ++v) {
        if (!visited[v]) {
            DFS(G, v); //对尚未访问的顶点调用DFS
        }
    }
}

int main() {
    Mgraph G;
    CreateUDN(G);
    printf("深度优先遍历:");
    DFSTraverse(G);
    return 0;
}

查找的实现

编写程序实现:

        1、建立顺序表。

        2、分别实现顺序查找、二分查找。

顺序查找从第一个元素开始逐个与需要查找的元素进行比较,当比较到元素值相同时返回此时的下标。二分查找,设有一个从小到大的序列,取中间的元素进行比较,若等于需要查找的元素则返回中间元素的下标,若需要查找的元素大于中间元素则再从右边查找,若需要查找的元素小于中间元素则再从左边查找,这样每次减少一半的查找范围。 


/*
**1、建立顺序表。
**2、分别实现顺序查找、二分查找。
*/
#include<stdio.h>
#define MAXSIZE 100

typedef int KeyType;
typedef struct {
    KeyType key;
}ElemType;

typedef struct{
    ElemType *elem;
    int length;
}SeqList;

int CreatList(SeqList &ST){
    ST.elem=new ElemType[MAXSIZE+1];
    if(!ST.elem)  return -1;
    printf("请输入顺序表的长度,表长不大于%d:",MAXSIZE);
    scanf("%d",&ST.length);
    printf("输入元素值:");
    for (int i=1;i<=ST.length;i++) { //i=0;i<ST.length错误 
        scanf("%d",&ST.elem[i].key);
    }
}

int Search_Seq(SeqList ST,KeyType key){
    int i;
    ST.elem[0].key=key;
    for(i=ST.length;ST.elem[i].key!=key;--i);
    return i;
} 

int Search_Bin (SeqList ST,KeyType key) {
    int low=1,high=ST.length;
	int mid;
	while(low<=high){
		mid=(low+high)/2;
		if(key==ST.elem[mid].key){ 
			return mid;
		} 
		else if(key<ST.elem[mid].key){
			high=mid-1;
		} 
		else{
			low=mid+1;
		} 
	}
	return -1;
} 

int main(){
    int n;
    int index;
    SeqList ST;
    CreatList(ST);
    printf("输入待查询的值:");
    scanf("%d",&n);
    printf("通过顺序查找:\n");
    index=Search_Seq(ST,n);
    printf("此数据在表中的位置为:%d\n",index);
    printf("通过二分查找:\n");
    index=Search_Bin(ST,n);
    printf("此数据在表中的位置为:%d\n",index);
    return 0;
}

内部排序的实现

编写程序实现:

        1、建立待排序表。

        2、分别实现直接插入排序、希尔排序。(希尔排序要求必做)

        3、要求显示输入待排序的序列和输出排序后的序列。

直接插入排序每次将一个待排序元素与已排序的元素逐一进行比较,直到找到合适的位置。希尔排序首先选择一个步长length/2,按照步长step进行分组即步长是多少就分成多少组,然后分别对每一组进行直接插入排序,然后改变步长step/2,然后再按照步长分组后分别对每一组进行直接插入排序,重复此步骤直到步长为0结束。

/*
**1、建立待排序表。
**2、分别实现直接插入排序、希尔排序。(希尔排序要求必做)
**3、要求显示输入待排序的序列和输出排序后的序列。
*/
#include<stdio.h>
#define MAXSIZE 100
typedef struct{
    int data[MAXSIZE];
    int length;
}SeqList;

void CreateList(SeqList &L, int n){
    L.length = n+1; 
    printf("请输入元素:\n");
    for(int i=1; i<=n; i++){
        scanf("%d",&L.data[i]);
    }
}

void PrintList(SeqList L){
    for(int i=1; i<L.length; i++){
        printf("%d ",L.data[i]);
    }
}

void InsertSort(SeqList &L){
    int i,j;
    for(i=2; i<L.length; i++){
        if(L.data[i] < L.data[i-1]){
            L.data[0] = L.data[i];
            for(j=i-1; L.data[0]<L.data[j]; j--){
                L.data[j+1] = L.data[j];
            }
            L.data[j+1] = L.data[0];
        }
    }
}

void ShellSort(SeqList &L){
    int d,i,j;
    int n = L.length-1;
    for(d=n/2; d>=1; d=d/2){
        for(i=d+1; i<=n; i++){
            if(L.data[i] < L.data[i-d]){
                L.data[0] = L.data[i];
                for(j=i-d; j>0&&L.data[0]<L.data[j]; j-=d){
                    L.data[j+d] = L.data[j];
                }
                L.data[j+d] = L.data[0];
            }
        }
    }
}

int main(){
    SeqList L;
    int n;
    printf("请输入线性表的长度:\n");
    scanf("%d",&n);
    CreateList(L, n);
    printf("待排序的序列为:\n");
    PrintList(L);
    printf("\n直接插入排序:\n");
    InsertSort(L);
    PrintList(L);
    printf("\n希尔排序:\n");
    ShellSort(L);
    PrintList(L);
    return 0;
}

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值