数据结构丿丶线性表


线性表存储及相关操作

 线性表是由同类型数据元素构成有序序列的线性结构

  • 顺序存储
struct LNode
{
	ElemType Data[MAXSIZE];       /*ElemType 可以是预先定义的struct类型*/
	int last;      /*指示最后一个元素的下标*/
};
typedef struct LNode *List;   /*指向结构的指针*/
struct LNode L;
List PtrL;

初始化

List MakeEmpty()
{
	List PtrL;
	PtrL=(List)malloc(sizeof(struct LNode));
	PtrL->last=-1;
	return PtrL;
}

查找

int Find(List PtrL,ElemType X)
{
	int i=0;
	while(i<= PtrL ->last&&PtrL->Data[i]!=X)  i++;  /*结构体可以整体比较和赋值*/
	if(i>PtrL->last) return -1;
	else return i;
}

插入

void Insert(List Ptrl, ElemType x,int i)
{
	if(PtrL->last=MAXSIZE-1) 
		printf("表满“);
    else if(i<1||i>last+2)
    	printf("位置不合法“);
    else
    {
    		for(int j=Ptrl->last;j>=i-1;j--)
    				PtrL->Data[j+1]=PtrL->Data[j];
    		PtrL->Data[i-1]=X;
    		PtrL->last++}
}

删除

void Delete(List PtrL,int i)
{
	if(i<1||i>PtrL->last+1) 
		printf("不存在第%d个元素”,i);
	for(int j=i;j<=PtrL ->last;j++)
	{
		PtrL->Data[j-1]=PtrL->Data[j];
	}
	ptrL->last--;
}

  • 链式存储
struct LNode
{
	ElemType data; /*ElemType可以是预先定义的struct类型*/
	struct LNode *next;  /*下一个结点的位置,如为NULL则表示到了末尾*/
};
typedef struct LNode *List;   /*指向结构的指针*/
struct LNode L;
List PtrL;

初始化(头结点视为第0个结点)

List MakeEmpty()
{
	List PtrL;
	PtrL=(List)malloc(sizeof(struct LNode));
	PtrL->next=null;
	return PtrL;
}

求表长

int Length(List PtrL) /*PtrL为头指针,指向第一个结点(假设无头结点)*/
{
	List  p=PtrL;
	int j=0;
	while(p)
	{
		p=p->next;
		j++;
	}
	return j;
}

查找(分为按序号和按值查找)

List(int k, List PtrL) /*头指针原本即指向第一个结点的地址*/
{
	List p=Ptrl;
	int i=1;  
	for(p!=null&&i<k)
	{
		p=p->next; /* p是指针即地址,而不是下一个结点的next值 */
		i++;
	}
	if(i==k) return p;
	else  return null;
}

插入

List Insert( List PtrL, ElementType X, int i)  /*无头结点则要判断是否为插入第一个结点*/
{
    List p,s;  /*p表示插入点前一个结点,s表示插入的结点*/
    if(i= =1)
    {
    		s=(list)malloc(sizeof(struct LNode));
    		s->data=X;
            s->next=PtrL;
            return s;
     }
     else
     {
    		p=Find(i-1,PtrL);           
  		    if ( p==NULL ) 
      		  printf("插入位置参数错误\n");
    		else 
   		    { 
       				 s = (list)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
       				 s->Data = X; 
       				 s->Next = p->next;
      			     p->Next = s;
      			     return PtrL;
   			 }
     }
 }

删除

List Delete( List PtrL,int i)
{
    List p,s;
   if(i= =1)    
   {
   		s=PtrL;
   		if(PtrL) PtrL=PtrL->next;
   		else return NUll;
   		free(s);
   		return PtrL;
   }
   else
   {
   		p=Find(i-1,PtrL);
   		if(p||p->next) printf("第%d个结点不存在,i);
   		else 
   		{
   			s=p->next;
   			p->next=s->next;
   			free(s);
   			return PtrL;
   		}
   }
}

建表
 链表和顺序表不同,它是一种动态结构,整个可用存储空间可为多个链表共同享用,每个链表占用的空间不需预先分配划定,而是由系统按需即时生,因此,建立线性表的链式存储结构的过程就是一个动态生成链表的过程。因此,从空表的初始状态起,依次建立各元素结点,并逐个插入链表

List CreateList(int n)
{
	List PtrL=(list)malloc(sizeof(struct LNode));
	scanf("%d",&PtrL->data);
	PtrL->next=null;
	for(int i=0;i<n;i++)
	{
		List p=(list)malloc(sizeof(struct LNode));
		scanf("%d",&p->data);
		p->next=PtrL->next;
		PtrL->next=p;
	}
	return PtrL;
}

线性表应用

  • 有序表的合并

 顺序有序表
①创建一个表长为 m+n 的空表 LC
②指针 pc 初始化,指向 LC 的第一个元素
③指针 pa , pb 初始化,分别指向 LA 和 LB 的第一个元素
④当指针 pa , pb 均为到达相应的表尾时,则依次比较 pa , pb 所指向的元素值,从 LA ,LB 中摘取值更小的那个元素插入 LC 的末尾
⑤如果 pa 已到达表 LA 的末尾,则依次将 LB 的剩余元素插入 LC 的末尾
⑥如果 pb 已到达表 LB 的末尾,则依次将 LA 的剩余元素插入 LC 的末尾

void MergeList(List LA , List LB , List LC)
{
	LC.length=LA.length+LB.length; /*可以用线性表结构的last表示*/
	LC.data=(ElemType*)malloc(LC.lenth * sizeof(ElemType)); /*ElemType为类型说明*/
	
	ElemType *pa,*pb,*pc;
	pa=LA->data; pb=LB->data; pc=LC->data;
	
	int i,j;
	for(i=1,j=1;i<=LA.length&&j<=LB.length;)
	{
		if(*pa<=*pb)
		{ 
			*pc++ = *pa++;			 i++;
		}
		else 
		{ 
			*pc++ = *pb++;			 j++;
		}
	}
	while(i++ <= LA.length) *pc++ = *pa++;
	while(j++ <= LB.length) *pc++ = *pb++;	
}
  • 链式有序表
①指针 pa 、pb 初始化,分别指向 LA 和 LB 的第一个元素
②LC 的头结点取 LA 的头结点
③指针 pc 初始化,指向 LC 的头结点
④当指针 pa 、pb 均为到达相应的表尾时,则依次比较 pa ,、pb 所指向的元素值,从 LA 、LB 中摘取元素值更小的那个结点插入 LC 的末尾
⑤将非空链表的剩余段插入到 pc 所指结点之后
⑥释放 LB 的头结点
void MergeList(List LA , List LB , List LC)
{
	List LC=LA;
	List pa,pb,pc;
	pa=LA->next; pb=LB->next; 
	pc=LC
	
	while(pa&&pb)   /*LA 和 LB 均未达到表尾*/ 
	{
		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;    /*链接剩余段*/
	
	free(LB);
}
  • 多项式的运算

多项式的表示

typedef struct PNode
{
	float coef;  /*系数*/
	int expn;  /*指数*/
	struct PNode *next;
} 
typedef struct PNode *Polynomial;   /*指向结构的指针*/

多项式的创建(建表过程中需要保证多项式链表是个有序表)

①创建一个只有头结点的空链表
②根据多项式的项的个数n,循环n次执行以下操作
 - 生成一个新结点 *s
 - 输入多项式当前项的系数和指数赋给新节点 *s 的数据域
 - 设置前驱指针 former 循链找到并指向要插入项的前驱结点,初值指向头结点
 - 设置后继指针 latter 循链指向并指向要插入项的后继结点,初值指向首元结点
 - 将结点插入前驱、后继结点之间

Polynomial P=(Polynomial)malloc(sizeof(struct PNode));
p->next=NULL;

void  CreatePoly(Polynomial P,int n)
{
	Polynomial s
	for(int i=1;i<=n;i++)
	{
		s = (Polynomial)malloc(sizeof(struct PNode));
		cin>>s->coef>>s->expn;
		former = P;  latter = P->next;
		
		while(latter&&latter->expn < s->next)
		{
			former=latter;
			latter=latter->next;
		}
		
		s->next=latter;  former->next=s;
	}
}

多项式相加

①指针 pa 和 pb 初始化,分别指向单链表 Pa 、Pb 的首元结点
②pc 指向结果多项式的当前结点,初值为 pa
③pa 和 pb 均未到达相应表尾时,则循环比较 pa、pb 所指结点对应的指数
 - 若 pa->next = pb->next 将两个结点的系数相加,如果和不为零,则修改 pa 所指结点的系数值,同时删除 pb 所指结点,如果为零,则删除 pa、pb 所指结点
 -若 pa->next < pb->next 将 pa 所指结点插入结果链表
 -若 pa->next > pb->next 将 pb 所指结点插入结果链表
④将非空多项式的剩余段插入到 pc 所指结点之后
⑤释放 pb 的头结点

 void AddPoly(Polynonial Pa,Polynomial Pb)
 {
	 Polynonial pa,pb,pc;
	 pa=Pa->next; pb=Pb->next;
	 pc=Pa;
	 while(pa&&pb)
	 {
	 	if(pa->expn==pb->expn)
	 	{
	 		float sum=pa->coef + pb->coef;
	 		if(sum!=0)
	 		{
	 			pa->coef = sum;
	 			pc->next=pa; pc=pa; pa=pa->next;
	 			
	 			Polynonial delete=pb;  /*释放pb结点*/
	 			pb=pb->next; 
	 			free(pb);
	 		}
	 		else
	 		{
	 			Polynonial delete=pa;  /*释放pa和pb结点*/
	 			pa=pa->next; 
	 			free(pa);
	 			
	 			delete=pb; 
	 			pb=pb->next; 
	 			free(pb);
	 		}
	 	}
	 	else if(pa->expn<pb->expn)
	 	{
	 		pc->next=pa; pc=pa; pa=pa->next;
	 	}
	 	else
	 	{
	 		pc->next=pb; pc=pb; pb=pb->next;
	 	}
	 }
	 pc->next=pa?pa:pb;  /*链接剩余段*/
	 
	 free(Pb);
 } 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值