02-线性表

Posted 我是纪予哇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02-线性表相关的知识,希望对你有一定的参考价值。

一、PTA实验作业

1.题目1:6-2 顺序表删除重复元素

2. 设计思路

typedef struct{
	int data[maxsize];//数值
	int length;//长度
}SqList;
typedef SqList *List;//用List替代*,方便后面代码书写
**主函数**
int i,n,a[maxsize],顺序表L,其中i为循环变量,n表示顺序表长度,数值a存放元素的值
输入n; 
	for  i=0 to i=n-1
	   输入数值并存入数组a;
	   建立顺序表
           删除重复元素
	   输出删除结束后顺序表  
	   销毁顺序表
       end for
**建立顺序表**
void CreateSqList(List &L,int a[],int n){
	int i
	创建头结点L
        L->length=0;
		if(n==0)return
	否则
	for i=0 to i=n-1
                把数组中元素依次赋给顺序表中元素	
		 顺序表长度加一
       end for
**输出顺序表**
void DispSqList(List L){
	int i;
	如果顺序表长度不为0
		for i=0 to i=L->length-2
        输出顺序表元素的值
          end for
}
**删除重复元素**
void DelSameNode(List &L){
   int i,j,k,flag=0,flag用来判断是否找到重复值
   for i=0 to i<L->length
   	for  j=i+1 to j=L->length-1
   	 如果L->data[i]等于L->data[j]) 即存在重复元素
   	 	flag=1;
   	 	跳出循环
  end for
  如果flag等于1
   	for k=j to k=L->length-1
   	 	从第j+1个元素开始后面的元素依次往前挪
   	 		flag=0,flag赋零,为下一次查找做准备
   	 		顺序表长度减一
                        i--为下一轮遍历做准备
           end for
}

3.代码截图

4.PTA提交列表说明。

(1)错误1:删除结果错误

题中测试数据能过,但是当输入5 1 2 2 2 2时发现输出结果为1 2 2,删除不彻底?调试发现第三个元素,即第二次出现2后,才进入遍历查找重复元素,导致输出多出
一个2

(2)错误2:空表

换用flag判断来删除重复元素,并增加i--,即将循环开始位置前移一个,保证所有重复元素都被遍历到。但这次出现空表错误,输入测试数据0时,发现输出一串数字,在输出函数中控制顺序表长度大于0才输出,提交,答案正确!

1.题目2:6-4集合的基本运算

2. 设计思路

typedef struct LNode	//定义单链表结点类型
{
  	ElemType data;
    struct LNode *next;
} LinkList;
**主函数**
int main()
{
	LinkList *ha,*hb,*hc;
	ElemType a[100]={0};//数组初始化
	ElemType b[100]={0};
	int i=0;
	char ch;
	当输入的字符不是换行符时
		将元素依次存入数组a
	建立链表ha
	同理 当输入的字符不是换行符时
                将字符存入数组b
	建立链表ha
	输出链表ha,hb
	对链表ha,hb中元素进行排序
	输出排序后的链表ha,hb
        建立新链hc
	求ha,hb的并集,即ha,hb剔除多余重复元素后的全部元素,将这些元素存入hc
	输出hc
	求ha,hb的交集,即ha,hb中均存在的元素并将这些元素存入hc
	输出hc
        求ha,hb的差集,即ha,hb剔除所有重复元素后的全部元素并将这些元素存入hc
	输出hc
	销毁链ha,hb,hc
	return 0;
}
***输出函数*
void DispList(LinkList *L){
	LinkList *p;
	p指向第一个节点
	遍历链表,输出各节点元素 
}
**构造函数**
void CreateListR(LinkList *&L,ElemType a[],int n){
	LinkList *s,*r;
 	int i;
 	创建头结点L
 	r指向头结点
 	for i=0 to i=n-1
 		 创建数据节点s
 		将数组a中元素依次赋给节点s
 		r->next=s
 		r=s
 	end for
 	r->next=NULL;//尾节点next域置为NULL
}
**销毁函数**
void DestroyList(LinkList *&L){
	LinkList *pre=L,*p=L->next;//pre指向头结点,p指向第一个节点
	当p!=NULL
		释放pre节点
		pre,p同步后移,指向下一个节点
	循环结束后,释放尾结点
}
**排序函数**
void sort(LinkList *&L){
	LinkList *p,*pre,*q;
	p指向L第二个数据节点
	L->next->next=NULL;//构造只喊一个数据节点的有序表
	当p!=NULL
		q保存p节点后继节点的指针
		pre指向头结点
		当pre->next!=NULL并且pre->next->data<p->data
		 pre指向下一个节点,找到要插入的位置
		 在pre后插入p
		 p=q//扫描余下节点
	}
**求并集**
void Union(LinkList *ha,LinkList *hb,LinkList *&hc)
{
	LinkList *s,*pa,*pb,*pc; 
       创建头结点hc;    
       pa指向链ha的第一个节点,pb指向链hb的第一个节点,pc指向hc的头结点
      当pa!=NULL且pb!=NULL 
        如果pa->data<pb->data
           创建数据节点s
            s->data=pa->data;  
 	    pc->next=s
 	    pc=s
            pa=pa->next;  
         如果 pa->data>pb->data
            创建数据节点s  
            s->data=pb->data;  
            pc->next=s
            pc=s
            pb=pb->next;  
        如果 pa->data=pb->data
             创建数据节点s  
            s->data=pa->data;  
            pc->next=s;  
            pc=s;  
            pa=pa->next;  
            pb=pb->next;  
  循环结束后
    当pb!=NULL,即hb链未遍历完
        pa=pb;  
    当pa!=NULL
        创建数据节点s 
        s->data=pa->data;  
        pc->next=s;  
        pc=s;  
        pa=pa->next;  
    pc->next=NULL;  //尾节点next域置为NULL
}
**求交集**
void InterSect(LinkList *ha,LinkList *hb,LinkList *&hc)
{
	  LinkList *s,*pa,*pb,*pc; 
       创建头结点hc;    
       pa指向链ha的第一个节点,pb指向链hb的第一个节点,pc指向hc的头结点
       当pa!=NULL  
    {
    	     pb指向链hb的第一个节点
             当pb!=NULL
              {
    		如果pb->data=pa->data
	    		创建数据节点s 
	            s->data=pa->data;  
	            pc->next=s;  
	            pc=s;
	        }
			pb=pb->next;  
		}
		pa=pa->next;
	}
    pc->next=NULL; //尾节点next域置为NULL   
}
**求差集**
void Subs(LinkList *ha,LinkList *hb,LinkList *&hc)
{
	LinkList *pa,*pb,*pc,*s;
        pa指向链ha的第一个节点
	int flag=0;  //flag用来判断是否有重复元素
        创建头结点hc;     
       pc指向hc的头结点
    当pa!=NULL
    {
    	pb指向链hb的第一个节点
    	当pb!=NULL
         {
    	    如果pb->data==pa->data
    	    	flag=1,跳出循环
		   pb=pb->next;
	    }
	   如果flag==0
           {
	       创建数据节点s   
            s->data=pa->data;  
            pc->next=s;  
            pc=s;  
		}
	    pa=pa->next;
	    flag=0;
	}
    pc->next=NULL;  //尾节点next域置为NULL  
}

3.代码截图





4.PTA提交列表说明。

(1)错误1:答案错误
一开始很奇怪三个函数输出的结果是一样的,修改好几次后面的函数,其余俩个函数不是输出不了就是输出一样。后来发现是没有申请数据节点,直接指向ha,hb的数据节点,求并集时链还可以连起来,后来再链新链时可能指针就乱了,通过申请新的数据节点,然后指向这个数据节点,进行交,并,差集运算,运行结果对了
(2)错误2:格式错误
仔细根据题目要求,修改了输出函数,答案正确

1.题目3:7-2 一元多项式的乘法与加法运算

2. 设计思路

typedef struct LNode	//定义单链表结点类型
{
  	ElemType data;//系数
  	ElemType power;//次方
    struct LNode *next;
} LinkList;
**主函数**
int main()
{
	LinkList *ha,*hb,*hc;
	创建链表ha,hb,hc
	计算ha,hb中元素构成单项式的乘积,将结果存入链表hc
        hc中元素的按次方递减排列
	输出链表hc
	计算ha,hb中元素构成单项式的乘积,将结果存入链表hc
        hc中元素的按次方递减排列
	输出链表hc
	销毁链表ha,hb,hc
	return 0;
}
**构造函数**
void CreateListR(LinkList *&L){
	LinkList *s,*r;
 	int e1,e2,i,n;e1用来存放系数,e2用来存放次方,n表示元素个数
 	输入n
 	创建头结点L
 	r=L;
 	for i=0 to i=n-1
 		创建数据节点s
	        输入e1,e2
 		s->data=e1;
 		s->power=e2;
 		r->next=s;
 		r=s;
 	end for
 	r->next=NULL;//尾节点next域置为NULL
}
**销毁链表**
void DestroyList(LinkList *&L){
	LinkList *pre,*p;
        pre指向头结点,p指向第一个节点
	当p!=NULL
		释放pre节点
		pre,p同步后移,指向下一个节点
	循环结束后,释放尾结点
}
**输出链表hc**
void DispList(LinkList *L){
	LinkList *p;
	p指向第一个节点;
	如果p==NULL
		输出NULL
   	遍历链表,输出各项的系数和次方
        如果系数为0 则不输出
        如果结果是零多项式输出0 0
}
**加法函数**
void add(LinkList *ha,LinkList *hb,LinkList *&hc){
	LinkList *pa,*pre,*pb,*s;
	创建头结点hc
	hc->next=NULL//链表初始化
	pre指向hc头结点;
	pa指向ha第一个节点;
	pb指向hb第一个节点;
	 当pa!=NULL且pb!=NULL时  
    {  
      遍历ha,hb,如果有次方相同项则合并同类项,否则按次方由大到小连接:
       如果pa->power<pb->power
       	   创建数据节点s
                s->data=pb->data; 
		s->power=pb->power; 
            pre->next=s;  
            pre=s;   
            pb指向下一个节点;  
       如果pa->power>pb->power
         	创建数据节点s
            s->data=pa->data;  
            s->power=pa->power; 
            pre->next=s;  
            pre=s;  
            pa指向下一个节点;  
       如果pa->power=pb->power
       	   创建数据节点s
            s->data=pa->data+pb->data;
	    s->power=pa->power; 
		如果s->data==0 让s->power=0;
            pre->next=s;  
            pre=s;  
            pa,pb均指向一个节点
    }
    如果pb还没有遍历完
        pa=pb;  
    当 pa!=NULL 
    {  
       创建数据节点s
        s->data=pa->data; 
	s->power=pa->power;  
        pre->next=s;  
        pre=s;  
        pa指向下一个节点 
    }  
      pre->next=NULL;  //尾节点next域置为NULL
}
**乘法函数**
void multipy(LinkList *ha,LinkList *hb,LinkList *&hc){
	LinkList *pa,*pre,*pb,*s;
	创建头结点hc
	hc->next=NULL//初始化
	pre指向头结点hc;
	pa指向ha第一个节点;
	pb指向hb第一个节点;
	当pa!=NULL
		pb=hb->next;
		当pb!=NULL
			创建数据节点s 
			 s->data=pa->data*pb->data; 
	                 s->power=pa->power+pb->power;  
                         pre->next=s;  
                         pre=s;  
	       pb=pb->next;
       pa=pa->next;	
   pre->next=NULL;//尾节点next域置为NULL
}
**排序函数**
void sort(LinkList *&hc){
	LinkList *p,*pre,*q,*r;
	p指向hc第二个数据节点
	hc->next->next=NULL;//保证只有一个数据节点
	r=hc;
	当p!=NULL
		q=p->next;
		pre=hc;
		当pre->next!=NULL且pre->next->power>p->power
                       交换俩个节点位置
			pre=pre->next;
		        p->next=pre->next;
		       pre->next=p;
		       p=q
	        当r->next!=NULL
		   如果r->data=0
			r->power=0;
		如果相邻俩项次方一样,合并同类项 
                如果r->data=0,r->power=0;
          r->next=r->next->next;
                删除相邻俩项后者
      r=r->next;
}

3.代码截图





4.PTA提交列表说明。

错误1:输入数据有0 0输出不对
在输出函数控制为0时不输出,以及零多项式输出0 0

错误2:

输入2 1 0 0 0 后发现程序崩溃,增加对输入时的合并同类项考虑,但是,依旧段错误。。。
2 0 0 1 0

二、截图本周题目集的PTA最后排名

1.顺序表PTA排名

2.链表PTA排名

3.我的总分:213

三、本周学习总结

1.谈谈你本周数据结构学习时间是如何安排,对自己安排满意么,若不满意,打算做什么改变?

这周空余时间,像没课的时候或者晚上都在完成PTA作业或者预习作业,PTA保证平均每天有一题正确的进度吧。目前觉得还是比较满意,一般到截止日期前题集已经基本上做的差不多了,不会很赶,每天适量代码,在学也不会太累,也不会太占用其他科目学习时间。遇到问题一般是先调试,自己解决不了,会去询问学长,一般最后才会选择借阅同学的代码,找差异

2.谈谈你对线性表的认识?

我对线性表的感觉就是,顺序表比链表好懂,但是各有各的好处,顺序表适合查找操作,链表适合插入删除操作,针对问题选择合适的表,效率会差很多

线性表总结

  • 1.顺序表有关
    (1)建表
    (2)顺序表初始化
    (3)销毁线性表
    (4)按元素查找
    (5)插入数据元素
    (6)删除数据元素
    (7)排序
    (8)合并
    (9)区间删除
  • 2.链表有关
    (1)插入,删除节点
    (2)建立单链表(头插法,尾插法)
    (3)初始化
    (4)排序
    (5)合并
    (6)区间删除
    (4)元素查找

3.代码Git提交记录截图

四、阅读代码

炳辉同学的一元多项式的乘法与加法运算




代码功能:实现一元多项式的乘法和加法计算

优点:
这题我和炳辉同学的思路差不多,都是实现加法,乘法,合并同类项,排序这几个功能,但是对于一些特殊情况我的代码不是运行奔溃就是结果错误,所以,我主要是学习他对于这些特殊值的考虑和处理

  • 对于有系数为0的项,他利用if(p->data==0) continue;这种跳出循环继续下一轮循环,来实现系数为0无输出
  • 用flag做标记,用if(flag==1) printf("0 0")来实现零多项式输出0 0

以上是关于02-线性表的主要内容,如果未能解决你的问题,请参考以下文章

第02次作业-线性表

第02次作业-线性表

博客作业02---线性表

第02次作业-线性表

第02次作业-线性表

第02次作业-线性表