学习链表的结尾就是一些使用链表的基本实例,比如约瑟夫环问题等。今天做了做一元多项式求和的链表实现,其中主要的思想就是一个普通的尾插法链表,主要的区别也只是有coef和exp两个数据元素了,再有就是求和实质其实就是两个链表的相加操作

主要的思想分别有:

  • 首先确定一条主链,让主链去加第二条链,两链相加主要需要判断的就是每一项的指数大小。
  • ①如果L1的指数小于L2的指数,不需要发生变化,让主链移动到下一个元素。
  • ②如果L1的指数大于L2的指数,则L1的前一结点的next指针需要发生移动,以及带动第二条链的指针移动。
  • ③如果两个指数相等,则进行coef系数相加操作。
  • 1、如果系数相加后等于0,则进行两条链对此结点的delete操作。
  • 2、如果不为0,只需delete第二条链的结点,第一条链系数改变即可。

结点的定义

struct Node
{
	int coef;
	int exp;
	Node* next;
};

coef是系数,exp是指数,next是指向下一节点的指针。

无参构造函数的实现

Linklist()
	{
		Node* r = NULL, * s = NULL;
		first = new Node;
		r = first;
		int coef, exp;
		while (1)
		{
			cout << "请输入系数和指数:";
			cin >> coef >> exp;
			if (coef == 0 || exp == 0)
				break;
			s = new Node;
			s->coef = coef;
			s->exp = exp;
			r->next = s;
			r = s;
		}
		r->next = NULL;
	}

这是一个基本的尾插法构造链表的程序,我们在这里定义如果其中有一项输入为0时代表输入结束。

重载+号运算符,实现两条链相加

Linklist operator+(Linklist &l)
	{
		Node* pre = first, * p = pre->next;
		Node* qre = l.first, * q = qre->next;
		Node* temp = NULL;
		while (p != NULL && q != NULL) // 保证两个结点不是空的
		{
			if (p->exp < q->exp) // 第一种情况,直接转移本链的指针即可
			{
				pre = p;
				p = p->next;
			}
			else if (p->exp > q->exp) // 第二种情况
			{
				temp = q->next; // 设置临时的变量,储存下q->next的指针
				pre->next = q; // 改变pre的后继为q,使主链在p结点之前再多加入一个结点
				q->next = p; // q的后继继续接p
				pre = q; // 以下的三个操作是对于第二条链的操作
				q = temp;
				qre->next = q;
			}
			else // 第三种情况,当指数相等时的情形
			{
				p->coef = p->coef + q->coef;
				if (p->coef == 0) // 等于0时,删除p结点
				{
					pre->next = p->next;
					delete p;
					p = pre->next;
				}
				else
				{
					pre = p;
					p = p->next;
				}
				qre->next = q->next;
				delete q; // 无论什么情况,都需要把q链上的结点删除掉
				q = qre->next;
			}
		}
		if (p == NULL)
			pre->next = q; // 还有一部操作就是如果p链空了,直接把q链上后面的结点接到p链后方,成为同一条链
		l.first->next = NULL;
		return *this;
	}

主要看注释

输出函数

	void Print()
	{
		Node* p = first->next;
		if (p != NULL)                            
			cout << p->coef << "x^" << p->exp;
		p = p->next;
		while (p != NULL)
		{
			if (p->coef > 0)
				cout << " + " << p->coef << "x^" << p->exp;
			else
				cout << " + " << p->coef << "x^" << p->exp;
			p = p->next;
		}
		cout << endl;
	}

这个也就是一个基本链表输出操作

主函数测试

int main()
{
	Linklist l1;
	l1.Print();
	Linklist l2;
	l2.Print();
	cout << "----------------------" << endl;
	l1 = l1 + l2;
	l1.Print();
	return 0;
}



全文代码

#include<iostream>
using namespace std;
struct Node
{
	int coef;
	int exp;
	Node* next;
};
class Linklist
{
	Node* first;
public:
	Linklist()
	{
		Node* r = NULL, * s = NULL;
		first = new Node;
		r = first;
		int coef, exp;
		while (1)
		{
			cout << "请输入系数和指数:";
			cin >> coef >> exp;
			if (coef == 0 || exp == 0)
				break;
			s = new Node;
			s->coef = coef;
			s->exp = exp;
			r->next = s;
			r = s;
		}
		r->next = NULL;
	}
	Linklist operator+(Linklist &l)
	{
		Node* pre = first, * p = pre->next;
		Node* qre = l.first, * q = qre->next;
		Node* temp = NULL;
		while (p != NULL && q != NULL)
		{
			if (p->exp < q->exp)
			{
				pre = p;
				p = p->next;
			}
			else if (p->exp > q->exp)
			{
				temp = q->next;
				pre->next = q;
				q->next = p;
				pre = q;
				q = temp;
				qre->next = q;
			}
			else
			{
				p->coef = p->coef + q->coef;
				if (p->coef == 0)
				{
					pre->next = p->next;
					delete p;
					p = pre->next;
				}
				else
				{
					pre = p;
					p = p->next;
				}
				qre->next = q->next;
				delete q;
				q = qre->next;
			}
		}
		if (p == NULL)
			pre->next = q;    
		l.first->next = NULL;
		return *this;
	}
	void Print()
	{
		Node* p = first->next;
		if (p != NULL)                            
			cout << p->coef << "x^" << p->exp;
		p = p->next;
		while (p != NULL)
		{
			if (p->coef > 0)
				cout << " + " << p->coef << "x^" << p->exp;
			else
				cout << " + " << p->coef << "x^" << p->exp;
			p = p->next;
		}
		cout << endl;
	}
};
int main()
{
	Linklist l1;
	l1.Print();
	Linklist l2;
	l2.Print();
	cout << "----------------------" << endl;
	l1 = l1 + l2;
	l1.Print();
	return 0;
}

后来仔细考虑了一下这个一元多项式求和,在处理系数和指数时存在的两条链指针互调还是需要好好学习的,之前在链表的学习中是没有遇见过的,今天积累到了


还是想继续考虑一下如果我输入的指数不是按照顺序的该咋办      (lll¬ω¬)hhh

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐