[数据结构]第二章--线性表(读书笔记4)

LinkList.h

#include "c1.h"

/*具有实用意义的线性链表,一个带头结点的线性链表*/
typedef struct LNode{/*结点类型*/
	ElemType data;
	struct LNode *next;
}*Link,*Position;

typedef struct{/*链表类型*/
	Link head,tail;/*分别指向线性表中的头结点和最后一个结点*/
	int len;/*指示线性表中数据元素的个数*/
}LinkList;

Status MakeNode(Link *p, ElemType e)
{ /* 分配由p指向的值为e的结点,并返回OK;若分配失败。则返回ERROR */
	*p = (Link)malloc(sizeof(LNode));
	if(!*p){
		return ERROR;
	}
	(*p)->data = e;
	return OK;
}
void FreeNode(Link *p)
{ /* 释放p所指结点 */
	free(*p);
	*p=NULL;
}
Status InitList(LinkList *L)
{ /* 构造一个空的线性链表 */
	Link p;
	p = (Link)malloc(sizeof(LNode)); /* 生成头结点 */
	if(p){
		p->next = NULL;
		(*L).head = (*L).tail = p;
		(*L).len = 0;
		return OK;
	}
	else{
		return ERROR;
	}
}
Status ClearList(LinkList *L)
{ /* 将线性链表L重置为空表,并释放原链表的结点空间 */
	Link p,q;
	if((*L).head != (*L).tail){/* 不是空表 */
		p = q = (*L).head->next;
		(*L).head->next = NULL;
		while(p != (*L).tail){
			p = q->next;
			free(q);
			q = p;
		}
		free(q);
		(*L).tail = (*L).head;
		(*L).len = 0;
	}
	return OK;
}
Status DestroyList(LinkList *L)
{ /* 销毁线性链表L,L不再存在 */
	ClearList(L); /* 清空链表 */
	FreeNode(&(*L).head);
	(*L).tail = NULL;
	(*L).len = 0;
	return OK;
}
Status InsFirst(LinkList *L, Link h, Link s) /* 形参增加L,因为需修改L */
{ /* h指向L的一个结点,把h当做头结点,将s所指结点插入在第一个结点之前 */
	s->next = h->next;
	h->next = s;
	if(h == (*L).tail){ /* h指向尾结点 */
		(*L).tail = h->next; /* 修改尾指针 */
	}
	(*L).len++;
	return OK;
}
Status DelFirst(LinkList *L, Link h, Link *q) /* 形参增加L,因为需修改L */
{	/* h指向L的一个结点,把h当做头结点,删除链表中的第一个结点并以q返回。 */
	 /* 若链表为空(h指向尾结点),q=NULL,返回FALSE */
	//if ((*L).head == (*L).tail || (*L) == NULL || h == NULL){
	//	*q = NULL;
	//	return FALSE;
	//}
	*q = h->next;
	h->next = h->next->next;
	if( !h->next ){ /* 删除尾结点 */
		(*L).tail = h; /* 修改尾指针 */
	}
	(*L).len--;
	return TRUE;
}
Status Append(LinkList *L,Link s)
{	/* 将指针s(s->data为第一个数据元素)所指(彼此以指针相链,以NULL结尾)的 */
	/* 一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新 */
	/* 的尾结点 */
	int i = 1;
	(*L).tail->next = s;
	while ( s->next ){
		s = s->next;
		i++;
	}
	(*L).tail = s;
	(*L).len += i;
	return OK;
}
Position PriorPos(LinkList L, Link p)
{	/* 已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置 */
	/* 若无前驱,则返回NULL */
	Link q = L.head->next;
	if(q == p){ /* 无前驱 */
		return NULL;
	}
	else{
		/* q不是p的直接前驱 */
		while (q->next != p){
			q = q->next;
		}
		return q;
	}
}
Status Remove(LinkList *L,Link *q)
{ /* 删除线性链表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点 */
	Link p=(*L).head;
	if((*L).len == 0) /* 空表 */
	{
		*q=NULL;
		return FALSE;
	}
	while(p->next != (*L).tail){
		p = p->next;
	}
	*q = (*L).tail;
	p->next = NULL;
	(*L).tail = p;
	(*L).len--;
	return OK;
}
Status InsBefore(LinkList *L, Link *p, Link s)
{	/* 已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前, */
	/* 并修改指针p指向新插入的结点 */
	Link q;
	q = PriorPos(*L,*p); /* q是p的前驱 */
	if(!q){ /* p无前驱 */
		q=(*L).head;
	}
	s->next = *p;
	q->next = s;
	*p = s;
	(*L).len++;
	return OK;
}
Status InsAfter(LinkList *L, Link *p, Link s)
{	/* 已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后, */
	/* 并修改指针p指向新插入的结点 */
	if( *p == (*L).tail ){ /* 修改尾指针 */
		(*L).tail = s;
	}
	s->next = (*p)->next;
	(*p)->next = s;
	*p = s;
	(*L).len++;
	return OK;
}
Status SetCurElem(Link p,ElemType e)
{ /* 已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值 */
   p->data=e;
   return OK;
}
ElemType GetCurElem(Link p)
{ /* 已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值 */
	return p->data;
}
Status ListEmpty(LinkList L)
{	/* 若线性链表L为空表,则返回TRUE,否则返回FALSE */
	if(L.len){
		return FALSE;
	}
	else{
		return TRUE;
	}
}
int ListLength(LinkList L)
{ /* 返回线性链表L中元素个数 */
	return L.len;
}
Position GetHead(LinkList L)
{ /* 返回线性链表L中头结点的位置 */
	return L.head;
}
Position GetLast(LinkList L)
{ /* 返回线性链表L中最后一个结点的位置 */
	return L.tail;
}
Position NextPos(Link p)
{	/* 已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置 */
	/* 若无后继,则返回NULL */
	return p->next;
}
Status LocatePos(LinkList L, int i, Link *p)
{ /* 返回p指示线性链表L中第i个结点的位置,并返回OK,i值不合法时返回ERROR */
	int count = 0;
	if( i < 0 || i > L.len){
		return ERROR;
	}
	*p = L.head;
	for(count = 0; count < i; count++){
		*p = (*p)->next;
	}
	return OK;
}
Position LocateElem(LinkList L,ElemType e,Status (*compare)(ElemType,ElemType))
{	/* 返回线性链表L中第1个与e满足函数compare()判定关系的元素的位置, */
	/* 若不存在这样的元素,则返回NULL */
	Link p = L.head;
	do{
		p = p->next;
	}while (p && !compare(p->data, e) );
	return p;
}
Status ListTraverse(LinkList L, void(*visit)(ElemType))
{ /* 依次对L的每个数据元素调用函数visit()。一旦visit()失败,则操作失败 */
	Link p=L.head->next;
	int j;
	for(j=1;j<=L.len;j++){
		visit(p->data);
		p = p->next;
	}
	printf("\n");
	return OK;
}
Status OrderInsert(LinkList *L, ElemType e, int (*comp)(ElemType,ElemType))
{ /* 已知L为有序线性链表,将元素e按非降序插入在L中。(用于一元多项式) */
	Link o,p,q;
	q = (*L).head;
	p = q->next;
	/* p不是表尾且元素值小于e */
	while (p != NULL && comp(e, p->data) < 0){
		q = p;
		p = p->next;		
	}
	o = (Link)malloc(sizeof(LNode)); /* 生成结点 */
	o->data = e; /* 赋值 */
	q->next = o;
	o->next = p;
	(*L).len++;
	if(!p){ /* 插在表尾 */
		(*L).tail = o; /* 修改尾结点 */
	}
	return OK;
}
Status LocateElemP(LinkList L,ElemType e,Position *q,int(*compare)(ElemType,ElemType))
{	/* 若升序链表L中存在与e满足判定函数compare()取值为0的元素,则q指示L中 */
	/* 第一个值为e的结点的位置,并返回TRUE;否则q指示第一个与e满足判定函数 */
	/* compare()取值>0的元素的前驱的位置。并返回FALSE。(用于一元多项式) */
	Link p = L.head,pp;
	do
	{
		pp = p;
		p = p->next;
	}while(p && (compare(p->data, e) < 0)); /* 没到表尾且p->data.expn<e.expn */
	if( !p || compare(p->data,e) > 0){ /* 到表尾或compare(p->data,e)>0 */
		*q = pp;
		return FALSE;
	}
	else{ /* 找到 */
		*q = p;
		return TRUE;
   }
}

多项式表示:

typedef LinkList polynomial;
#define DestroyPolyn DestroyList

Status OrderInsertMerge(LinkList *L,ElemType e,int(* compare)(term,term))
{ /* 按有序判定函数compare()的约定,将值为e的结点插入或合并到升序链表L的适当位置 */
	Position q,s;
	if(LocateElemP(*L,e,&q,compare)) /* L中存在该指数项 */
	{
		q->data.coef += e.coef; /* 改变当前结点系数的值 */
		if(!q->data.coef) /* 系数为0 */
		{ /* 删除多项式L中当前结点 */
			s=PriorPos(*L,q); /* s为当前结点的前驱 */
			if(!s){ /* q无前驱 */
				s=(*L).head;
			}
			DelFirst(L,s,&q);
			FreeNode(&q);
		}
		return OK;
	}
	else{ /* 生成该指数项并插入链表 */
		if(MakeNode(&s,e)) /* 生成结点成功 */
		{
			InsFirst(L,q,s);
			return OK;
		}
		else{ /* 生成结点失败 */
			return ERROR;
		}
	}
}
int cmp(term a,term b) /* CreatPolyn()的实参 */
{ /* 依a的指数值<、=或>b的指数值,分别返回-1、0或+1 */
	if (a.expn == b.expn){
		return 0;
	}
	else{
		return (a.expn - b.expn) / abs(a.expn - b.expn);
	}
}
void CreatPolyn(polynomial *P,int m) /* 算法2.22 */
{ /* 输入m项的系数和指数,建立表示一元多项式的有序链表P */
	Position q,s;
	term e;
	int i;

	InitList(P);
	printf("请依次输入%d个系数,指数:\n",m);
	for(i = 1; i <= m; ++i){ /* 依次输入m个非零项(可按任意顺序) */
		scanf("%f,%d", &e.coef, &e.expn);
		if(!LocateElemP(*P, e, &q, cmp)){ /* 当前链表中不存在该指数项,cmp是实参 */
			if( MakeNode(&s,e) ){ /* 生成结点并插入链表 */
				InsFirst(P, q, s);
			}
		}
	}
}
void PrintPolyn(polynomial P)
{ /* 打印输出一元多项式P */
	Link q;
	q = P.head->next; /* q指向第一个结点 */
	printf("  系数    指数\n");
	while(q){
		printf("%f  %d\n",q->data.coef, q->data.expn);
		q = q->next;
	}
}
void AddPolyn(polynomial *Pa,polynomial *Pb) /* 算法2.23 */
{ /* 多项式加法:Pa=Pa+Pb,并销毁一元多项式Pb */
/*
1.指针qa所指结点的指数值 < 指针qb所指结点的指数值
  则应摘取qa指针所指结点插入到"和多项式"链表中去
2.指针qa所指结点的指数值 == 指针qb所指结点的指数值
  则将两个结点中的系数相加,若和数不为零则修改qa所指结点的系数值,同时释放qb结点
3.指针qa所指结点的指数值 〉指针qb所指结点的指数值
  则应摘取指针qb所指结点插入到"和多项式"链表中去
*/
	Position ha,hb,qa,qb;
	term a,b;
	ha = GetHead(*Pa);
	hb = GetHead(*Pb); /* ha和hb分别指向Pa和Pb的头结点 */
	qa = NextPos(ha);
	qb = NextPos(hb); /* qa和qb分别指向Pa和Pb中当前结点(现为第一个结点) */
	while(!ListEmpty(*Pa) && !ListEmpty(*Pb) && qa)
	{ /* Pa和Pb均非空且ha没指向尾结点(qa!=0) */
		a = GetCurElem(qa);
		b = GetCurElem(qb); /* a和b为两表中当前比较元素 */
		switch(cmp(a,b)){
		case -1:
			ha = qa; /* 多项式Pa中当前结点的指数值小 */
			qa = NextPos(ha); /* ha和qa均向后移一个结点 */
			break;
		case 0:
			qa->data.coef += qb->data.coef;
			/* 两者的指数值相等,修改Pa当前结点的系数值 */
			if(qa->data.coef == 0){ /* 删除多项式Pa中当前结点 */
				DelFirst(Pa,ha,&qa);
				FreeNode(&qa);
			}
			else{
				ha = qa;
			}
			DelFirst(Pb, hb, &qb);
			FreeNode(&qb);
			qb = NextPos(hb);
			qa = NextPos(ha);
			break;
		case 1:
			DelFirst(Pb, hb, &qb); /* 多项式Pb中当前结点的指数值小 */
			InsFirst(Pa, ha, qb);
			ha = NextPos(ha);
			qb = NextPos(hb);
		}
	}
	if(!ListEmpty(*Pb)){
		(*Pb).tail = hb;
		Append(Pa, qb); /* 链接Pb中剩余结点 */
	}
	DestroyPolyn(Pb); /* 销毁Pb */
}
void Opposite(polynomial Pa)
{ /* 一元多项式系数取反 */
	Position p;
	p = Pa.head;
	while(p->next){
		p = p->next;
		p->data.coef *= -1;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	polynomial p,q;
	int m;

	printf("请输入第一个一元多项式的非零项的个数:");
	scanf("%d",&m);
	CreatPolyn(&p,m);
	printf("请输入第二个一元多项式的非零项的个数:");
	scanf("%d",&m);
	CreatPolyn(&q,m);
	AddPolyn(&p,&q);
	printf("两个一元多项式相加的结果:\n");
	PrintPolyn(p);
	printf("请输入第三个一元多项式的非零项的个数:");
	scanf("%d",&m);
	CreatPolyn(&q,m);
	AddPolyn(&p,&q);
	printf("两个一元多项式相加的结果(另一种方法):\n");
	PrintPolyn(p);
	printf("请输入第四个一元多项式的非零项的个数:");
	scanf("%d",&m);
	CreatPolyn(&q,m);
//	SubtractPolyn(&p,&q);
//	printf("两个一元多项式相减的结果:\n");
	PrintPolyn(p);
	printf("请输入第五个一元多项式的非零项的个数:");
	scanf("%d",&m);
	CreatPolyn(&q,m);
//	MultiplyPolyn(&p,&q);
//	printf("两个一元多项式相乘的结果:\n");
	PrintPolyn(p);
	DestroyPolyn(&p);
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

进击的横打

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

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

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

打赏作者

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

抵扣说明:

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

余额充值