线性表的实际应用

一、线性表的合并:
假设利用两个线性表La,Lb分别表示两个集合a,b,求这a∪b.
算法步骤:
依次取出Lb中的每个元素,执行以下操作:
① 在La中查找该元素
②如果找不到,则把这个元素插入到La的最后。

void union( List &La, List Lb) {
    La_len=ListLength(La); 
	Lb_len=ListLength(Lb);
	for(i=1: i<=Lb len; i++){
       GetElem(Lb, i, e);//依次看看Lb中每个值又没有在La中有,没有就插入La
       if(!Locate Elem(La, e)) Listinsert(&La, ++La len, e);
    }  
}

完整代码:

#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
typedef struct Node{
	int data;
	struct Node *next;
}node, *linklist;

int len(linklist L);
int get_elem(linklist L, int i);
int check_elem(linklist L, int e);
void insert_elem(linklist &L, int e);
void create(linklist &L, int n);
int main()
{
	linklist L, M;
	create(L, 4);
	create(M, 3);
	
	int i, j, k;
	for (i = 1; i <= len(M); ++i){
		int temp = get_elem(M, i);
		if (!(check_elem(L, temp))) insert_elem(L, temp);
	}
	
	linklist p = L->next;
	while(p){
		printf("%d ", p->data);
		p = p->next;
	}

	return 0;
}

void create(linklist &L, int n){
	L = new Node;
	L->next = NULL;
	linklist r = L;
	int i;
	for (i = 0; i < n; ++i){
		linklist p = new Node;
		cin >> p->data;
		p->next = NULL;
		r->next = p;
		r = p;
	}	
}

int len(linklist L){
	linklist p = L->next;
	int j = 0;
	while(p){
		p = p->next;
		++j;
	}
	return j;
}

int get_elem(linklist L, int i){
	linklist p = L->next;
	int j = 1;
	while(p && j<i){
		p = p->next;
		++j;
	}
	if (!p || j>i)return ERROR;
	return p->data; 
}

int check_elem(linklist L, int e){
	linklist p = L->next;
	while(p && p->data != e){
		p = p->next;
	}
	if (!p) return 0;
	else return OK;
}

void insert_elem(linklist &L, int e){
	linklist p = new Node, r = L->next;
	p->next = NULL;
	p->data = e;
	while(r->next) r = r->next;
	r->next = p;
}

二、有序表的合并:
已知线性表La和Lb中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列。

算法步骤:
①创建空表Lc
②依次从La或Lb中摘取元素值较小的结点插入Lc表的最后,直至其中一个表变空为止
③继续将La或Lb其中一个表的剩余结点插入在Lc的最后

1.顺序表

void MergeList_Sq(SqList LA, SqList LB, SqList &LC) {
    pa = LA.elem; 
	pb = LB.elem;	//指针pa和pb的初值分别指向两个表的第一个元素(基地址)
	LC.length = LA.length + LB.length; 	//新表长度为待合并两表的长度之和 
	LC.elem = new ElemType[LC.length]; //为合并后的新表分配一个数组空间 
	pc = LC.elem; //指针pc指向新表的第一个元素 
	pa_last = LA.elem + LA.length - 1; //指针pa_last指向LA的最后一个元素 
	pb_last = LB.elem + LB.length - 1; //指针pb_last指向LB的最后一个元素
    while (pa <= pa_last && pb <= pb_last) { //两个表都非空 
		if (*pa <= *pb) *pc++ = *pa++;  //依次“摘取”两表中值较小的结点 
		else *pc++ = *pb++; 
    }
	while (pa <= pa_last) *pc++ = *pa++;//B表已到达表尾,将LA中剩余元素加入LC 
	while (pb <= pb_last) *pc++ = *pb++;//A表已到达表尾,将LB中剩余元素加入LC 
}
 
//循环的次数取决于LA,LB中数据的元素多少,Lc的长度取决于LA,LB中数据的元素多少
//时间复杂度和空间复杂度都是O(ListLength(La)+ListLength(Lb))

2.链表:

void MergeList L(LinkList &La, LinkList &Lb, LinkList &Lc) {
    pa = La->next; pb = Lb->next;
	pc = Lc = La; //用La的头结点作为Lc的头结点 
	while (pa && pb) { 
		if (pa->data <= pb->data) {pc->next = pa; pc = pa; pa = pa->next;}
		else {pc->next = pb; pc = pb; pb = pb->next;} 
    }
    pc->next = pa ? pa : pb;//插入剩余段 
    delete Lb;//释放Lb的头结点 
}
//时间复杂度最坏情况是La,Lb轮流出现要加入的元素,必须要La,Lb中每一个元素都要走一遍,即O(ListLength(La)+ListLength(Lb))
//在原有链表基础上操作,不需要额外空间,因此空间复杂度是O(1)

三、一元多项式的运算(加法)
1.一般多项式(建议用顺序表实现)
在这里插入图片描述

2.稀疏多项式(建议用链表实现,因为不需要存入0,节省了内存空间)
在这里插入图片描述
在这里插入图片描述

typedef struct PNode{
	float coef;
	int expn;
	struct PNode *next;
}PNode, *Polynomial;

建立多项式链表:


void Create Polyn(Polynomial &P, int n){
	//输入m项的系数和指数,建立表示多项式的有序链表P 
	P = new PNode;
	P->next = NULL; //先建立一个带头结点的单链表 
	for (i = 1;i <= n; ++i){ //依次输入n个非零项 
		s = new PNode;//生成新结点 
		cin >> s->coef >> s->expn;//输入系数和指数 
        pre = P;//pre用于保存q的前驱,初值为头结点 
        q = P->next; //q初始化,指向首元结点 
		while (q && q->expn < s->expn){//找到第一个大于输入项指数的项"q 
			pre = q; 
			q = q->next;
        }
		s->next = q; //将输入项s插入到q和其前驱结点pre之间 
		pre->next = s;
    }
}

多项式相加:

typedef struct Node
{
    int coef;//coefficient:系数
    int index;//index:指数
    struct Node *next=NULL; 
}node;
 
//多项式相加算法
node *addpolylist(node *la,node *lb, node &lb)//polynomial:多项式
{
    node temp = new node;
    node *pa, *pb, *pc;
    lc = la; //以la的头结点作为lc的头结点
    pa = la->next; pb = lb->next; pc = lc;//将pa,pb分别指向la,lb的首元结点
    while (pa && pb)//分别遍历,两个链表指针非空为循环条件,就是两串都还没加完
    {
        if (pa->index < pb->index) //pa指向结点系数大于pb
        {
            pc->next = pa;
            pa = pa->next;
            pc = pc->next;
        } 
        else if (pa->index > pb->index)
        {
            pc->next = pb;
            pb = pb->next;
            pc = pc->next;
        }
        else
        {
            temp = new node;
            temp->coef = pa->coef + pb->coef;
            if (temp->coef)//系数相加非零
            {
                temp->index = pa->index;
                pc->next = temp;
                pa = pa->next;
                pb = pb->next;
                pc = pc->next;
            }
            else
            {
                delete temp;
                pa = pa->next;
                pb = pb->next;
            }
        }
    }
    pc->next = pa ? pa : pb;//把pa或pb剩余没加完的非空列表加在pc后面
    return lc;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值