数据结构:线性表(学习篇1)

概念:线性表是零个或多个数据元素组成的有限序列。

  ☼特点:线性表的元素是有序的

                若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其余的元素有一个前驱和一个后继

                 线性表强调是有限的

线性表插入操作:

•如果插入位置不合理,抛出异常。

•如果线性表长度大于等于数组长度,则抛出异常或动态增加数组容量。

•从最后一个元素开始向前遍历到第i个元素,分别将它们都向后移动一个位置。

•将要插入元素填入位置i处。

•线性表长为1。

线性表(单链表)的读取:

获得链表第i个数据的算法思路:

•声明一个节点p指向链表第一个节点,初始化j从1开始

•当j<i时,就遍历链表,让p的指针向后移动,不断指向下一节点,j+1。

•若到链表末尾p为空,则说明第i个元素不存在,否则查找成功,返回节点p的数据。

链表的优点在于链表实现了真正的动态存储,不需要关心存储容量的问题。缺点在于它失去了随机访问的能力。

这是链表的节点定义:

public class list<E> {
	//首先定义一个private修饰,只能在linkedlist类内访问的内部类存储节点信息
	private class Node{
		public E e;
		public Node next;
	}
//多态,根据用户传来的参数个数不同
	public Node(E e,Node next){
		this.e=e;
		this.next=next;
	}
	public Node(E e){
		this(e,null);
	}
	public Node(){
		this(null,null);
	}
	@Override
	public String toString(){
		return e.toString;
	}

}

向链表中一个一个地添加元素将这些节点挂接起来:

应用:一元多项式运算器:

一元多项式在计算机中存储时仅需要存储非0的系数项。为了实现任意多项式的运算,考虑到运算中有较多的插入删除操作,选择单链表作为存储结构比较方便,每个节点有3个域:系数,指数,指针。其数据结构如下所示:

typedef struct Polynomial{
	float coef;    //系数 
	int expn;     //指数 
	struct Polynomail *next;    //指向下一个节点的指针 
};

多项式计算器的算法实现如下:

1.建立多项式

通过键盘输入一组多项式的系数和指数,用尾插法建立一元多项式的链表。以输入系数0为结束标志,并约定建立一元多项式链表时,总是按指数从小到大的顺序排列。

2.输出多项式

从单链表第一个元素开始,逐项读出系数和指数,安多项式的形式进行输出即可。

3.两个多项式相加

以单链表pa和pb分别表示两个一元多项式A和B,A+B的求和运算,就等同于单链表的求和问题

4.相减

將减数pb多项式的所有系数变成其相反数,然后使用两个多项式相加思想进行处理

5.多项式乘法

多项式乘法类似于将两个多项式相加,pa*pb,需要使用pb多项式中的每一项和pa多项式中的每一项进行相乘,然后进行多项式相加操作。

6.求多项式的值,需要输入变量x的值然后进行求职计算。

7.多项式的导数

需要根据导数公式对多项式的每一个节点求导,具体过程如下:

需要根据导数公式对多项式的每一个结点求导,具体过程如下:多项式当前结点指数为0,则其导数的系数为当前结点指数乘以系数,指数为当前节点的指数减1。

以下,是课本上给出的算法(C语言描述)

//建立多项式 
Polyn CreatePoly(){
	Polynomial *head,*rear,*s;
	int c,e;
	head=(Polynomial *)malloc(sizeof(Polynomial));   //建立多项式头结点
	rear=head;   //始终指向单链表的尾,便于尾插法建表
	scanf("%d,%d",&c,&e);//键入多项式的系数和指数项
	while(c!=0){      //若c=0,则代表多项式输入结束
     s=(Polynomial*)malloc(sizeof(Polynomial));
	 s->coef=c;
	 s->expn=e;
	 rear->next=s;   //在当前表尾插入
	 rear=s;
	 scanf("%d,%d",&c,&e); 
		
	} 
	 rear->next=NULL;//将表中最后一个节点的next置为null
	 return(null); 
}
//输出多项式
void PrintPolyn(Polyn P){
	Polyn q=p->next;
	int flag=1;
	if(!q){
		putchar('0');
		printf("\n");
		return;
	}
	while(q){
		if(q->coef>0&&flag!=1)   putchar('+');
		if(q->coef!=1&&q->coef!=-1){
			printf("%g",q->coef);
			if(q->expn==1)   putchar('X');
			else if(q->expn) printf("X^%d",q->expn);
		}else{
			if(q->coef==1)
			{
				if(q->coef==1){
					if(!q->expn)  putchar('1');
					else printf("X^%d",q->expn);
				}
				if(q->coef==-1){
					if(!q->expn)printf("-1");
					else if(q->expn==1)  printf("-X");
					else printf("-X%d",q->expn);
					
				}
			}
			q=q->next;
			flag++;
		}
	}
	printf("\n");
} 
//两个多项式相加
Polyn AddPolyn(Polyn pa,Polyn pb){
	Polyn qa=pa->next;
	Polyn qb=pb->next;
	Polyn headc,pc,qc;
	pc=(Polyn)malloc(sizeof(struct Polynomial));  //单链表pc用于保存pa+pb的和
	pc->next=NULL;
	headc=pc;
	while(qa!=NULL&&qb!=NULL)    //当两个多项式均未扫描结束时
	{
		qc=(Polyn)malloc(sizeof(struct Polynomial));
		if(qa->expn<qb->expn){
			qc->ceof=qa->ceof;
			qc->expn=qa->expn;
			qa=qa->next;
		}
		else if(qa->expn>qb->expn){
			qc->ceof=qa->ceof+qb->ceof;
			qc->expn=qa->expn;
			qa=qa->next;
			qb=qb->next; 
		}
		else{
			qc->ceof=qb->ceof;
			qc->expn=qb->expn;
			qb=qb->next;
		}
		if(qc->ceof!=0)
		{
		   qc->next=pc->next;	
		    pc->next=qc;
			pc=qc;	
		}else free(qc);
	 } 
	 //pa中如果有剩余项,就将剩余项插入到pc当中
	 while(qa!=null)
	 {
	 	qc=(Polyn)malloc(sizeof(struct Polynomial));
	 	qc->ceof=qa->ceof;
	 	qc->expn=qa->expn;
	 	qa=qa->next;
	 	qc->next=pc->next;
	 	pc->next=qc;
	 	pc=qc;
	  } 
	   //pb中如果有剩余项,就将剩余项插入到pc当中
	 while(qb!=null)
	 {
	 	qc=(Polyn)malloc(sizeof(struct Polynomial));
	 	qc->ceof=qb->ceof;
	 	qc->expn=qb->expn;
	 	qb=qb->next;
	 	qc->next=pc->next;
	 	pc->next=qc;
	 	pc=qc;
	  } 
	return headc;
} 
//两个多项式相减
Polyn substractPolyn(Polyn pa,Polyn pb) 
{
	Polyn h=pb;
	Polyn p=pb->next;
	Polyn pd;
	while(p)
	{
		p->coef*=-1;
		p=p->next;
	}
	pd=AddPolyn(pa,h);
	for(p=h->next;p;p=p->next)
	p->ceof*=-1;
	return pd;
}

找到链表的倒数第n个结点

分析:从表头节点开始遍历链表,让M表示链表的长度。得到长度后,计算M-n+1的值,然后从表头再遍历一遍就得到链表的长度。然后链表再从头遍历一次就能得到第M-n+1个结点。这个方法需要两次遍历:一次用于求链表的长度,另一次用于寻找从表头开始的第M-n+1个结点。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值