《数据结构》实验报告/课程设计:链表、二叉树

写在前面

本文提供数据结构课程实验之链表、二叉树相关内容,包括实验任务、核心代码和运行结果。若想获取完整实验报告和用于验收的可运行源代码,请点击下方链接跳转:
《数据结构》实验报告/源代码:链表与二叉树

实验一:链表

(一)实验目的

  1. 理解线性表的链式存储结构。
  2. 熟练掌握动态链表结构及有关算法的设计。
  3. 根据具体问题的需要,设计出合理的表示数据的链表结构,并设计相关算法。

(二)实验任务

  1. 对任意输入的一组数据,建立一个递增有序的单链表。
  2. 将单链表拆分成两个单链表,其中一个全为奇数,另一个全为偶数(尽量利用原存储空间)。
  3. 把单链表中的元素就地逆置(利用原表各结点的空间)。
  4. 用递增有序的链表A、B表示两个集合,设计算法求它们的并集。
  5. 删除非空的单循环链表的表尾结点。
  6. 判断一个双循环链表是否对称。

(三)实验方案及运行结果

  1. 对任意输入的一组数据,建立一个递增有序的单链表。
  • 核心算法:
void  list::display() {
	node* p = head->next;
	while (p != NULL) { cout << p->data << " "; p = p->next; }
	cout << endl;

}
void list::insert1(int x)
{
	node* u, * P;
	P = head;
	while (P->next != NULL && P->next->data < x)
		P = P->next;
	if (P->next == NULL || P->next->data > x)
	{
		u = new node;
		u->data = x;
		u->next = P->next;
		P->next = u;
		count++;
	}
}
  • 运行结果:

在这里插入图片描述
2. 将单链表拆分成两个单链表,其中一个全为奇数,另一个全为偶数(尽量利用原存储空间)。

  • 核心算法:
void list::devide(list* L, list* L1, list* L2)
{
	int x, i;
	for (i = 1; i < L->length() + 1; i++) {
		L->get_element(i, x);
		if (i % 2 != 0) {
			int j = 1;
			L1->insert(j, x);
		}
		else {
			int j = 1;
			L2->insert(j, x);
		}
	}
}
int main() {
	list L, L1, L2;
	L.create1();
	cout << "链表为:" << endl;
	L.display();
	L.devide(&L,&L1,&L2);
	cout << endl;
	cout << "链表的奇数项为:" << endl;
	L1.display();
	cout<<endl;
	cout << "链表的偶数项为:" << endl;
	L2.display();
	cout << endl;
	return 0;
}
  • 测试结果:

在这里插入图片描述
3. 把单链表中的元素就地逆置(利用原表各结点的空间)。

  • 核心算法:
void ReverseList(Seqlist &L)
{
	int t;
	if(L.length%2==0)    //顺序表元素个数为偶数
	{
		for(int i=0;i<L.length/2;i++)
		{
			t=L.pdata[i];
			L.pdata[i]=L.pdata[L.length-i-1];
			L.pdata[L.length-i-1]=t;
		}
	}
	else if(L.length%2==1)    //顺序表元素个数为奇数
	{
		for(int i=0;i<(L.length-1)/2;i++)
		{
			t=L.pdata[i];
			L.pdata[i]=L.pdata[L.length-i-1];
			L.pdata[L.length-i-1]=t;
		}
	}
}
int main()
{
	Seqlist L;
	InitList(L);    //初始化
	CreateList(L);    //建立
	cout<<"顺序表元素为:"<<endl;
	ListTraverse(L);    //原序输出
	ReverseList(L);    //逆置
	cout<<"逆置后的顺序表元素为:"<<endl;
	ListTraverse(L);    //逆置输出
	return 0;
}
  • 测试结果:

在这里插入图片描述
4. 用递增有序的链表 A 、B 表示两个集合,设计算法求它们的并集。

  • 核心算法:
void list:: minus_LinkList(list A,list B,list &C)
{
	node* tempA = A.get_head()->next;
	node* tempB = B.get_head()->next;
	node* tempC = C.get_head();
	int x;
	while (tempA != NULL)
	{
		node* s = new node;
		s->data = tempA->data;
		tempC->next = s;
		tempC = s;
		tempC->next = NULL;
		tempA = tempA->next;
	}
	tempC = C.get_head();
	while (tempB != NULL)
	{
		x = tempB->data;
		if (C.locate(x) == NULL)
		{
			node* s = new node;
			s->data = x;
			s->next = tempC->next;
			tempC->next = s;
		}
		tempB = tempB->next;
	}
}
int main() {
	list A, B, C;
	cout << "请输入L1:(以0结束)" << endl;
	A.create2();
	cout << "请输入L2:(以0结束)" << endl;
	B.create2();
	A.minus_LinkList(A, B, C);
	C.display();
	return 0;
}
  • 测试结果:

在这里插入图片描述
5. 删除非空的单循环链表的表尾结点。

  • 核心算法:
void LinkList::DelateTail()//删除表尾结点
{
    node *p,*q;
    p=q=rear->next;
    while(p->next!=rear)
    {
        p=p->next;
    }
    p->next=q;
    delete rear;
    rear=p;
}
void LinkList::PrintLinkList()//打印单链表
{
    node *p;
    p=rear->next;
    cout<<"链表中的元素为:"<<endl;
    while(p!=rear)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<p->data<<endl;
}
  • 运行结果:

在这里插入图片描述
6. 判断一个双循环链表是否对称

  • 核心算法:
int main()
{
	list l;
	node* h;
	h=l.create2(h);
	l.showlist2();
	cout<<endl;
	bool sym=l.symmetry(h);
	cout<<sym;
	return 0;
}
  • 测试结果:

在这里插入图片描述

实验二:二叉树

(一)实验目的

  1. 掌握二叉树的动态链表存储结构及表示。
  2. 掌握二叉树的三种遍历算法。
  3. 运用二叉树三种遍历的方法求解有关问题。

(二)实验任务

  1. 建立一棵采用二叉链表结构存储的二叉树。
  2. 分别对该二叉树进行先序、中序和后序遍历。
  3. 设计算法以输出二叉树中先序序列的前 k ( k >0)个结点的值。
  4. 求二叉树的高度。
  5. 求二叉树中叶子结点的数目。
  6. 按中序方式输出二叉树中各结点的值及其层次数。
  7. 复制一棵二叉树 T 到T1。
  8. 交换二叉树中每个结点的左右孩子指针的值。

(三)实验方案及运行结果

1.建立一棵采用二叉链表结构存储的二叉树,分别对该二叉树进行先序、中序和后序遍历

  • 核心算法:
void BinaryTree::visit(bnode* T)       //访问结点函数
{
	cout << T->data;
}
void BinaryTree::preorder(bnode* T)    //先序遍历
{
	if (T != NULL) {
		visit(T);
		preorder(T->lchild);
		preorder(T->rchild);
	}
}
void BinaryTree::inorder(bnode* T)    //中序遍历
{
	if (T != NULL)
	{
		inorder(T->lchild);
		visit(T);
		inorder(T->rchild);
	}
}
void BinaryTree::postorder(bnode* T) //后序遍历
{
	if (T != NULL)
	{
		postorder(T->lchild);
		postorder(T->rchild);
		visit(T);
	}
}
  • 测试结果:

在这里插入图片描述
2. 设计算法以输出二叉树中先序序列的前 k ( k >0)个结点的值

  • 核心代码:
int main() 
{
	tree t;
	bittree a=NULL;
	t.create(a);
	cin>>k;
	t.preorder_k(a);
	return 0;
}
  • 运行结果:

在这里插入图片描述
3. 求二叉树的高度

  • 核心算法:
int BinaryTree::treeheight(bnode* T)   //递归法求树高
{
	int height;
	if (T == NULL)
		return 0;
	else
		return max(treeheight(T->lchild), treeheight(T->rchild)) + 1 ;
}
  • 测试结果:

在这里插入图片描述
4. 求二叉树中叶子结点的数目

  • 核心算法:
int BinaryTree::DepthTree(bnode* root) //求叶子结点
{
	if (!root)
	{
		return 0;
	}
	else
	{
		if ((!root->lchild) && (!root->rchild))
		{
			return 1;
		}
		else
		{
			return (DepthTree(root->lchild) + DepthTree(root->rchild));
		}
	}
}
  • 测试结果:

在这里插入图片描述
5. 按中序方式输出二叉树中各结点的值及其层次数。

  • 核心算法:
void BinaryTree::in_traverse_level(bnode*& T, int n) 
{
	//对中序遍历算法进行改造
	if (T != NULL)
	{
		in_traverse_level(T->lchild, n + 1);
		cout << "节点:" << T->data << "  该节点层次:" << n << endl;;
		in_traverse_level(T->rchild, n + 1);
	}
}

void BinaryTree::copy(bnode* T, bnode*& S)
{
	if (T == NULL)
		S = NULL;
	else
	{
		S = new bnode;
		S->data = T->data;
		copy(T->lchild, S->lchild);
		copy(T->rchild, S->rchild);
	}
}
  • 测试结果:

在这里插入图片描述

6.复制一棵二叉树 T 到T1

int main() 
{
	tree t;
	bittree a=NULL;
	bittree a1;
	t.create(a);
	t.copytree(a,a1);
	t.preorder(a);
	cout<<endl;
	t.preorder(a1);	
}
  • 测试结果:

在这里插入图片描述
7. 交换二叉树中每个结点的左右孩子指针的值

  • 核心代码:
void BinaryTree::Switch(bnode*& T1, bnode*& T2) 
{
	bnode* t = T1;
	T1 = T2;
	T2 = t;
}
void BinaryTree::NodeSwap(bnode*& T) 
{
	if (T != NULL)
	{
		if (T->lchild != NULL && T->rchild != NULL)/ 
		{
			Switch(T->lchild, T->rchild);
		}
		else if (T->lchild != NULL && T->rchild == NULL)/ 
		{
			T->rchild = T->lchild;
			T->lchild = NULL;
		}
		else if (T->lchild == NULL && T->rchild != NULL)//如果T的左孩子为空且右孩子不为空
		{
			//将T的右子树变为左子树
			T->lchild = T->rchild;
			T->rchild = NULL;
		}
		else/ 
		{
		}
		NodeSwap(T->lchild);
		NodeSwap(T->rchild);
	}
	else
	{
		;
	}
}
  • 测试结果:

在这里插入图片描述

心得体会

  1. 通过双链表实验以及应用实验,对于链表这一数据结构理解更加深刻,对于头节点的作用更加明确,实验结果符合要求和逻辑。

  2. 熟练地掌握了二叉树的建立以及递归函数的调用,还了解了递归的逻辑以及终止条件。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

雲天外

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

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

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

打赏作者

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

抵扣说明:

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

余额充值