2.4有序表

本文详细介绍了有序表的概念,探讨了其在顺序表和链表中的存储结构,重点阐述了插入运算的ListInsert算法,以及针对两种存储结构的二路归并算法。还涉及了有序表的应用实例,如删除重复元素和两个有序列表的合并操作。
摘要由CSDN通过智能技术生成

2.4.1 有序表的概念

所谓有序表,是指这样的线性表,其中所有元素以递增或递减方式有序排列。        

后面讨论的有序表默认元素是以递增方式排列。

例如:L=(1,5,8,10,15,20)就是一个整数有序表。

注意:

既然有序表中元素逻辑关系与线性表的相同,有序表可以采用与线性表相同的存储结构。 

2.4.2 有序表的存储结构及其基本运算算法

在以顺序表或者链表存储有序表时,许多基本运算算法与线性顺序表或者链表的算法相同(不考虑优化)。 只有插入运算—ListInsert()算法有所差异。 

若以顺序表存储有序表,ListInsert()算法算法如下:

void ListInsert(SqList *&L,ElemType e)
{  int i=0,j;
   while (i<L->length && L->data[i]<e)
      i++;				//查找值为e的元素
   for (j=ListLength(L);j>i;j--)	//将data[i..n]后移一个位置
      L->data[j]=L->data[j-1]; 
   L->data[i]=e;
   L->length++;			//有序顺序表长度增1
}

 若以单链表存储有序表,ListInsert()的算法如下:

void ListInsert(LinkNode *&L,ElemType e)
{  LinkNode *pre=L,*p;

   while (pre->next!=NULL && pre->next->data<e)
	pre=pre->next; 	//查找插入结点的前驱结点pre

   p=(LinkNode *)malloc(sizeof(LinkNode));
   p->data=e;			//创建存放e的数据结点p
   p->next=pre->next;		//在pre结点之后插入p结点
   pre->next=p;
}

2.4.3 有序表的归并算法 

 

 采用顺序表存放有序表时,二路归并算法如下:

void UnionList(SqList *LA,SqList *LB,SqList *&LC)
{  int i=0,j=0,k=0;	 //i、j分别为LA、LB的下标,k为LC中元素个数
   LC=(SqList *)malloc(sizeof(SqList)); 	//建立有序顺序表LC
   while (i<LA->length && j<LB->length)
   {  if (LA->data[i]<LB->data[j])
      {  LC->data[k]=LA->data[i];
	  i++;k++;
      }
      else	       //LA->data[i]>LB->data[j]
      {  LC->data[k]=LB->data[j];
	  j++;k++;
      }
  }   
     while (i<LA->length)	//LA尚未扫描完,将其余元素插入LC中
     {	LC->data[k]=LA->data[i];
	i++;k++;
     }
     while (j<LB->length)	//LB尚未扫描完,将其余元素插入LC中
     {	LC->data[k]=LB->data[j];
	j++;k++;
     }
     LC->length=k;
}

 采用单链表存放有序表时,二路归并算法如下:

void UnionList1(LinkNode *LA,LinkNode *LB,LinkNode *&LC)
{  LinkNode *pa=LA->next,*pb=LB->next,*r,*s;
   LC=(LinkNode *)malloc(sizeof(LinkNode));	//创建LC的头结点
   r=LC;					//r始终指向LC的尾结点
   while (pa!=NULL && pb!=NULL)
   {  if (pa->data<pb->data)
      {  s=(LinkNode *)malloc(sizeof(LinkNode));  //复制结点
	  s->data=pa->data;
	  r->next=s;r=s;			//采用尾插法将s插入到LC中
	  pa=pa->next;
      }
      else
      {  s=(LinkNode *)malloc(sizeof(LinkNode));   //复制结点
	  s->data=pb->data;
	  r->next=s;r=s;			//采用尾插法将s插入到LC中
	  pb=pb->next;
      }
   }
   while (pa!=NULL)
   {  s=(LinkNode *)malloc(sizeof(LinkNode));    //复制结点
      s->data=pa->data;
      r->next=s;r=s;			//采用尾插法将s插入到LC中
      pa=pa->next;
   }
   while (pb!=NULL)
   {  s=(LinkNode *)malloc(sizeof(LinkNode));    //复制结点
      s->data=pb->data;
      r->next=s;r=s;			//采用尾插法将s插入到LC中
      pb=pb->next;
   }
   r->next=NULL			//尾结点的next域置空
}

2.4.4 有序表的应用

void dels(LinkNode *&L)
{  LinkNode *p=L->next,*q;
   while (p->next!=NULL) 
   {  if (p->data==p->next->data)	//找到重复值的结点
      {  q=p->next;			//q指向这个重复值的结点
         p->next=q->next;		//删除q结点
         free(q);
      }
      else				//不是重复结点,p指针下移
	  p=p->next;
   }
}

ElemType M_Search(SqList *A, SqList *B) //A、B的长度相同
{  int i=0, j=0, k=0;
   while (i<A->length && j<B->length)   //两个序列均没有扫描完
   {  k++;                              //当前归并的元素个数增1
      if (A->data[i]<B->data[j])        //归并较小的元素A->data[i]
      {  if (k==A->length)		    //若当前归并的是第n个元素
           return A->data[i];		    //返回A->data[i]
         i++;
      }
      else				    //归并较小的元素B->data[j]
      {  if (k==B->length)		    //若当前归并的是第n个元素
           return B->data[j];		    //返回B->data[j]
         j++; 
      }
   }
}

本节完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

万叶学编程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值