深入理解数据结构——链表应用

#include <iostream>
#include <string>

using namespace std;

typedef int Etype;     // 自定义链表的数据元素为整数。
//定义数据元素节点结构
typedef struct ChainNode
{
	Etype data;          // 存放结点的数据元素。
	ChainNode* next;  // 指向下一个结点的指针。
};

//ChainNode* p;   //p是指向数据元素结构的指针
//p->data表示当前数据元素的值
//p->next表示下一个元素的地址
//p的值是某数据节点的起始地址


typedef string HeadEtype;     // 自定义表头的数据元素为整数。
//定义表头结构
typedef struct HeadNode
{
	HeadEtype Hdata;           // 存放结点的数据元素。
	ChainNode* first;  // 指向下一个结点的指针。
};

//将表头结点和若干个数据节点链在一个组成一个链接表

//我们定义一个表头类型的执行变量,这个变量也是一个链表:
//HeadNode* L, * L1, *stud;
或者
//ChainNode L,  L1,  stud;

//如果表头节点和数据节点的结构是相同的,那么表头节点的结构也可以用
//数据节点的结构类型来定义:
// ChainNode* L, * L1, *stud;

//将表头节点指向数据节点
typedef HeadNode* ChainList;
//创建一个空链表
void CreatChainList(ChainList& L)//输入一个数据节点
{
	L = new HeadNode;
	L->first = NULL;//表头节点的链接域设为NULL
	L->Hdata = "HeadNode类型的数据值";//表头节点的数据域填入相应数据
}


//将第k个节点移动至表首

bool MoveFirstChainList(ChainList &L,int k) {

	if (k < 1 || L->first) return false;//第k个节点为0,或者为空表
	
	ChainNode* current = L->first;//current为第一个数据的地址

	if (k == 1) return true;//如果要移至表首数据就是第一个,就不用移动了
	else {
		ChainNode* q = L->first;

		for (int index = 1; index < k - 1; index++) {
			q = q->next;//
		}//q目前为第k-1个元素的地址
		if (!q || !q->next) return false;//第k-1个元素的地址和k素地址为空
		current = q->next;//current为k数据的地址
		q->next = current->next;//将k元素的地址替换为k+1数据的地址
	}
	    current->next = L->first;//将k元素的下一个元素换为原表第一个元素
		L->first = current;//将第一个元素的地址改为第k元素的地址
		return true;
}

//将线性表L逆向
bool InvertChainList(ChainList &L) {
	ChainNode *current;
	ChainNode* p = L->first;//p为第一个元素地址
	L->first = NULL;//将表头指向上一个元素,自然是NULL
	while (p) {
		current = p;//第一次循环,current为第一个元素地址
		p = p->next;//p替换为第二个元素的地址
		current->next = L->first;//当前元素想前指
		L->first = current;//表头指向下一个元素
	}
	//NULL<-1<-2.......<-first
	return true;
}

//多项式的相加运算
struct PolyNode {
	int exp;//指数
	float coef;//系数
	PolyNode* next;//下一元素地址
};

struct ChainNode {
	PolyNode data;//数据节点
	ChainNode* next;//下一数据节点地址
};

//多项式链表L1和L2相加
void AddPolyL1(ChainList& L1, ChainList& L2)
{
	ChainNode* p;//存L1
	ChainNode* q;//存L2
	ChainNode* p0;
	ChainNode* x;

	int choice;
	p = L1->first;
	q = L2->first;
	p0 = NULL;
	while (p && q) {//当前节点不为空
		if (p->data.exp > q->data.exp) choice = 1;
		if (p->data.exp == q->data.exp) choice = 2;//指数相等
		if (p->data.exp < q->data.exp) choice = 3;//较大指针指向下一个节点,较小节点不动
		switch (choice)
		{
		case 1:{
			p0 = p;//L1系数比较大
			p = p->next;//指向下一个节点
			break;
			}
		case 2: {//指数相等,将L1+l2存入L1
			p->data.coef = p->data.coef + q->data.coef;
			if (p->data.coef == 0) {
				p0->next = p->next;//p0指向下一节点
				delete p;//删除系数为0的节点
				p = p0->next;//p指向下一节点
			}
			else {
				p0 = p;//将结果存入结果链表中
				p = p0->next;//同时指向下一个节点
			}
			q = q->next;//指向下一个节点
			break;

		}
		case 3: {//L2系数比较大
			x = new ChainNode;
			x->data.coef = q->data.coef;
			x->data.exp = q->data.exp;
			x->next = p;//L1系数
			if (p0)
				p0->next = x;
			else
				L1->first = x;
			p0 = x;
			q = q->next; //q指向下一节点
			break;
		}
		}
	}

	while (q) {//对比较长的链表,逐一移动到结果链表p0中
		x = new ChainNode;
		x->data.coef = q->data.coef;
		x->data.exp = q->data.exp;
		x->next = NULL;
		if (!L1->first) L1->first = x;
		else p0->next = x;
		p0 = x;
		q = q->next;
	}
}

void AddPolyL3(ChainList& L1, ChainList& L2, ChainList& L3) {

	ChainNode* p, * q, * r, * x;

	int choice;
	float coef;
	p = L1->first;
	q = L2->first;
	r = L3->first;

	while (p && q) {
		if (p->data.exp > q->data.exp) choice = 1;
		if (p->data.exp == q->data.exp) choice = 2;//指数相等
		if (p->data.exp < q->data.exp) choice = 3;//较大指针指向下一个节点,较小节点不动

		switch (choice) {
		case 1: {//p指数比较大
			x = new ChainNode;//新建一个数据节点,用途是记录当前节点数据
			x->data.coef = p->data.coef;
			x->data.exp = p->data.exp;
			x->next = NULL;
			if (r)//
				r->next = x;//r下一个元素存入x
			else//r目前指向第一个元素
				L3->first = x;//将p指向的数据作为链表的第一个数据
			r = x;//r当前元素存入x
			p=p->next;//p指向下一个数据
			break;
		}
		case 2: {//指数相等
			coef = p->data.coef + q->data.coef;
			if (coef)//指数不为零
			{
				x = new ChainNode;//新建一个数据节点,用途是记录当前节点数据
				x->data.coef = coef;
				x->data.exp = p->data.exp;
				x->next = NULL;
				if (r)//
					r->next = x;//r下一个元素存入x
				else//r目前指向第一个元素
					L3->first = x;//将p指向的数据作为链表的第一个数据
				r = x;//r当前元素存入x
			}
			p = p->next;
			q = q->next;
			break;
		}
		case 3: {
			x = new ChainNode;//新建一个数据节点,用途是记录当前节点数据
			x->data.coef = q->data.coef;
			x->data.exp = q->data.exp;
			x->next = NULL;
			if (r)//
				r->next = x;//r下一个元素存入x
			else//r目前指向第一个元素
				L3->first = x;//将p指向的数据作为链表的第一个数据
			r = x;//r当前元素存入x
			q = q->next;//p指向下一个数据
			break;
		}
		}
	}
	while (q)//p的系数读取完了,继续将q后续的指数存入L3
	{
		x = new ChainNode;//新建一个数据节点,用途是记录当前节点数据
		x->data.coef = q->data.coef;
		x->data.exp = q->data.exp;
		x->next = NULL;
		if (r)//
			r->next = x;//r下一个元素存入x
		else//r目前指向第一个元素
			L3->first = x;//将p指向的数据作为链表的第一个数据
		r = x;//r当前元素存入x
		q = q->next;//p指向下一个数据
	}


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南叔先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值