实验1链表的插入和删除
【实验目的】
1、 了解单链表、循环链表和双链表的基本知识;
2、 掌握算法思想和数据结构的描述;
3、 掌握链表的插入、删除的相关语句及基本方法。
【实验步骤与要求】
1、 实验前的准备
(1) 了解C语言的基本概念;
(2) 了解C语言的基本段落。
2、 上机操作
(1) 了解链表的基本知识;
(2) 掌握算法思想和数据结构的描述;
(3) 掌握链表的插入、删除的相关语句及基本方法。
【实验内容】
设有两个无头结点的单链表,头指针分别为ha,hb,链中有数据域data,链域next,两链表的数据都按递增序存放,现要求将hb表归到ha表中,且归并后ha仍递增序,归并中ha表中已有的数据若hb中也有,则hb中的数据不归并到ha中,hb的链表在算法中不允许破坏。
【方法说明】
先定义结构体:
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
源代码1.1:
#include<stdio.h> #include<stdlib.h> #include<math.h> typedef int ElemType; typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList; void head_insert(LinkList *root,int x) { LNode *p=(LNode*)malloc(sizeof(LNode)); p->data=x; p->next=*root; *root=p; } void _union(LinkList *root1,LinkList *root2) { LNode *p=*root1,*q=*root2; LinkList *last=root1; while(p) { while(q&&q->data<=p->data) { if(q->data<p->data) { head_insert(last,q->data); last=&((*last)->next); } q=q->next; } last=&(p->next); p=p->next; } while(q) { head_insert(last,q->data); q=q->next; } } void show(LinkList p) { while(p) { printf("%d\n",p->data); p=p->next; } } int main() { LinkList ha=NULL,hb=NULL; head_insert(&ha,10); head_insert(&ha,5); head_insert(&ha,4); head_insert(&ha,1); head_insert(&hb,8); head_insert(&hb,5); head_insert(&hb,3); head_insert(&hb,2); printf("----A----\n"); show(ha); printf("----B----\n"); show(hb); _union(&ha,&hb); printf("----A----\n"); show(ha); printf("----B----\n"); show(hb); return 0; }
实验2 一元多项式相加
【实验目的】
1、了解链式存储结构的基本知识;
2、掌握算法思想和数据结构的描述;
3、结合一元多项式相加的运算规则。
【实验步骤与要求】
1、实验前的准备
(1)了解C语言的基本概念;
(2)了解C语言的基本段落。
2、上机操作
(1)了解链式存储结构的基本知识;
(2)掌握算法思想和数据结构的描述;
(3)掌握一元多项式相加的运算规则。
【实验内容】
结合书上第41页的例子,采用链式存储结构,讲两个线性链表表示的一元多项式相加,并输出。
【方法说明】
根据一元多项式相加的运算规则:对于两个一元多项式中所有指数相同的项,对应系数相加,若其和不为零,则构成“和多项式”中的一项;对于两个一元多项式中所有指数不相同的项,则分别复抄到“和多项式”中去。
代码2.1:
#include<stdio.h> #include<stdlib.h> #include<math.h> typedef struct{ int a,k; }ElemType; typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList; void head_insert(LinkList *root,ElemType e) { LNode *p=(LNode*)malloc(sizeof LNode); p->data.a=e.a; p->data.k=e.k; p->next=*root; *root=p; } void head_insert(LinkList *root,int a,int b) { LNode *p=(LNode*)malloc(sizeof LNode); p->data.a=a; p->data.k=b; p->next=*root; *root=p; } void tail_insert(LinkList *root,ElemType e) { LNode *last=*root,*p=(LNode*)malloc(sizeof LNode); p->data.a=e.a; p->data.k=e.k; p->next=NULL; if(last==NULL) { (*root)=p; return ; } while(last->next) { last=last->next; } last->next=p; } void _add(LinkList *root,LinkList *root1,LinkList *root2) { for(LNode *p=*root1,*q=*root2;p!=NULL||q!=NULL;) { if(q==NULL) { tail_insert(root,p->data); p=p->next; } else if(p==NULL) { tail_insert(root,q->data); q=q->next; } else { if(p->data.a<q->data.a) { tail_insert(root,p->data); p=p->next; } else if(p->data.a==q->data.a) { if(p->data.k+q->data.k!=0) { ElemType e=p->data;e.k+=q->data.k; tail_insert(root,e); } p=p->next; q=q->next; } else { tail_insert(root,q->data); q=q->next; } } } } void show(LinkList p) { while(p) { printf("%d %d\n",p->data); p=p->next; } } int main() { LinkList ha=NULL,hb=NULL; head_insert(&ha,10,1); head_insert(&ha,5,1); head_insert(&ha,4,1); head_insert(&ha,1,1); head_insert(&hb,8,1); head_insert(&hb,5,1); head_insert(&hb,4,-1); head_insert(&hb,3,1); head_insert(&hb,2,1); printf("----A----\n"); show(ha); printf("----B----\n"); show(hb); LinkList hc=NULL; _add(&hc,&ha,&hb); printf("----C----\n"); show(hc); return 0; }
实验3 二叉树的遍历
【实验目的】
1、 了解二叉树的前序和中序序列排列;
2、 将C语言同二叉树的数据结构联系起来;
3、 掌握生成的二叉树的链表结构;
4、 掌握如何按层次输出二叉树的所有结点;
5、 掌握如何将动态二叉树转换为静态二叉链表。
【实验内容要求】
1、实验前的准备
(1)了解二叉树的基本概念;
(2)了解二叉树的基本结构。
2、上机操作
(3)了解二叉树的前序和中序序列排列;
(4) 将C语言同二叉树的数据结构联系起来;
(5) 掌握生成的二叉树的链表结构;
(6) 掌握如何按层次输出二叉树的所有结点;
(7) 掌握如何将动态二叉树转换为静态二叉链表。
【实验内容】
创建一个二叉树,对这棵动态二叉树进行分析,将其用静态二叉链表表示。二叉树的动态二叉链表结构中的每个结点有三个字段:data,lchild,rchild。静态二叉链表是用数组作为存储空间,每个数组元素存储二叉树的一个结点,也有三个字段:data,lchild,rchild。lchild和rdhild分别用于存储左右孩子的下标。
【方法说明】
先定义结构体:
#include<stdio.h>
#include<stdlib.h>
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
此树中序遍历为:ABDG^^H^^^CE^^F^I^^
代码3.1:
#include<stdio.h> #include<stdlib.h> typedef struct BiTNode{ char data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; int cnt; void build(BiTree *B) { char a; scanf("%c",&a); if(a=='^') { *B=NULL; return ; } *B=(BiTNode*)malloc(sizeof(BiTNode)); (*B)->data=a; build(&((*B)->lchild)); build(&((*B)->rchild)); } int turn(BiTree B,BiTree b) { int st=1,cnt=0; b[++cnt]=*B; while(cnt!=st-1) { BiTNode e=b[st++]; if(e.lchild!=NULL) { b[++cnt]=*(e.lchild); b[st-1].lchild=(struct BiTNode *)cnt; } else b[st-1].lchild=(struct BiTNode *)0; if(e.rchild!=NULL) { b[++cnt]=*(e.rchild); b[st-1].rchild=(struct BiTNode *)cnt; } else b[st-1].rchild=(struct BiTNode *)0; } return cnt; } int main() { BiTree B; printf("请以中序输入该树:"); build(&B); printf("建树完成\n"); BiTNode b[20]; int cnt=turn(B,b); printf("转化完成,输出静态数组:\n"); for(int i=1;i<=cnt;i++) { printf("%d %c",i,b[i].data); if(b[i].lchild)printf(" left:%c/%d",b[(int)(b[i].lchild)].data,(int)(b[i].lchild)); else printf(" left:NO"); if(b[i].rchild)printf(" right:%c/%d\n",b[(int)(b[i].rchild)].data,(int)(b[i].rchild)); else printf(" right:NO\n"); } return 0; }//ABDG^^H^^^CE^^F^I^^
实验4 无向图的深度优先搜索
【实验目的】
1、 了解图的定义、特点,区分无向图和有向图的概念;
2、 了解图的数据结构和搜索方法;
3、 掌握无向图的邻接矩阵、邻接表的表示方法;
4、 写出无向图的深度优先搜索程序。
【实验内容要求】
1、 了解图的定义、特点,区分无向图和有向图的概念;
2、 了解图的数据结构和搜索方法;
3、 掌握无向图的邻接矩阵、邻接表的表示方法;
4、 写出无向图的深度优先搜索程序。
【实验内容】
设无向图G有n个点e条边,写一算法建立G的邻接多表,并按照深度优先搜索输出顶点,要求该算法时间复杂性为O(n+e),且除邻接多表本身所占空间之外只用O(1)辅助空间。
【方法说明】
邻接表定义:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define max 30
typedef struct edgenode{
int adjvex;
char info;
struct edgenode *next;
};
typedef struct vexnode{
char data;
struct edgenode *link;
}adjlist[max];
邻接矩阵定义:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define max 10
typedef struct vertex{
int num;
char data;
};
typedef struct graph{
struct vertex vexs[max];
int edges[max][max];
}adjmax;
代码4.1:
#include<stdio.h> #include<stdlib.h> #include<conio.h> #define max 30 struct edgenode{ int adjvex; struct edgenode *next; }; struct vexnode{ char data; struct edgenode *link; }adjlist[max]; bool visit[max]; void add_edge(int a,int b) { edgenode *p=(edgenode *)malloc(sizeof(edgenode)); p->adjvex=b; p->next=adjlist[a].link; adjlist[a].link=p; } void dfs(int root) { visit[root]=1; printf("%d %c\n",root,adjlist[root].data); for(edgenode *e=adjlist[root].link;e!=NULL;e=e->next) { if(!visit[e->adjvex])dfs(e->adjvex); } } void dfs_G(int n) { printf("dfs顺序:\n"); for(int i=0;i<n;i++) visit[i]=0; for(int i=0;i<n;i++) if(!visit[i])dfs(i); } int main() { int n,m,a,b;char c; printf("请输入结点数,边数:"); scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { adjlist[i].data=i+'A'; adjlist[i].link=NULL; } printf("请依次输入结点编码串:"); getchar(); for(int i=0;i<n;i++) { scanf("%c%*c",&c); adjlist[i].data=c; } printf("请输入各条边:"); for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); add_edge(a,b); } dfs_G(n); return 0; } /* 8 9 A B C D E F G H 0 1 1 3 1 4 4 7 3 7 0 2 2 6 2 5 5 6 */
实验5结合二叉树的二叉排序树设计
【实验目的】
1、 了解二叉排序树的定义,并结合二叉树的数据结构;
2、 掌握二叉排序树的排序方法。
【实验内容要求】
1、 了解二叉排序树的定义,并结合二叉树的数据结构;
2、 掌握二叉排序树的排序方法。
【实验内容】
二叉排序树采用二叉链表存储。写一个算法,删除结点值是X的结点。要求删除该结点后,此树仍然是一棵二叉排序树,并且高度没有增长(注:可不考虑被删除的结点是根的情况)。
【方法说明】
二叉排序树的定义:
#include<stdio.h>
#include<stdlib.h>
#define num 10
struct treenode{
int data;
struct treenode *lchild,*rchild;
};
代码5.1:
#include<stdio.h> #include<stdlib.h> #define num 10 typedef struct treenode{ int data; struct treenode *lchild,*rchild; }node,*BinTree; BinTree search(BinTree t,int key,BinTree *p) { BinTree last,bt; last=t; bt=t; while(bt) { if(bt->data==key) { *p=bt; return bt; } last=bt; if(bt->data>key)bt=bt->lchild; else bt=bt->rchild; } *p=last; return bt; } void insert(BinTree *bt,int key) { BinTree p,q,r; q=*bt; if(search(q,key,&p)==NULL) { r=(BinTree)malloc(sizeof(treenode)); r->data=key; r->lchild=r->rchild=NULL; if(*bt==NULL)*bt=r; else if(key<p->data)p->lchild=r; else p->rchild=r; } } int Bdelete(BinTree *bt,int key) { BinTree f,p,q,s; p=*bt;f=NULL; while(p&&p->data!=key) { f=p; if(p->data>key)p=p->lchild; else p=p->rchild; } if(p==NULL)return 0; if(p->lchild==NULL) { if(f==NULL)*bt=p->rchild; else if(f->lchild==p)f->lchild=p->rchild; else f->rchild=p->rchild; free(p); } else { q=p;s=p->lchild; while(s->rchild) { q=s; s=s->rchild; } if(q==p)q->lchild=s->lchild; else q->rchild=s->lchild; p->data=s->data; free(s); return 1; } return 0; } void show(BinTree root) { if(root) { show(root->lchild); printf("%d ",root->data); show(root->rchild); } } int main() { BinTree b=NULL; insert(&b,1); insert(&b,6); insert(&b,4); insert(&b,2); insert(&b,5); insert(&b,3); printf("建树完成-----\n"); show(b);puts(""); printf("删除节点3-----\n"); Bdelete(&b,3); show(b);puts(""); return 0; }