2.2順序表的算法

#include <stdio.h>
#include <iostream>

#define MaxSize 50

typedef int ElemType;

typedef struct
{
 ElemType data[MaxSize];
 int length;
}SqList;

void InitList(SqList& L)
{
 L.length=0;
}

//求指定位置元素值的算法
int GetElem(SqList L,int i,ElemType &e)
{
 if(i<1 || i>L.length)                 //邏輯位序
  return 0;
 e=L.data[i-1];
 return 1;
}

//按元素值查找的算法
int LocateElem(SqList L,ElemType e)
{
 int i=0;
 while(i<L.length && L.data[i]!=e)i++;
 if(i>=L.length)
  return 0;
 else
  return (i+1);
}

//插入數據元素的算法
int ListInsert(SqList &L,int i,ElemType e)
{
 int j;
 if(i<1 || i>L.length+1)             //邏輯位序
  return 0;
 i--;
 for(j=L.length;j>i;j--)
  L.data[j]=L.data[j-1];
 L.data[i]=e;
 L.length++;
 return 1;
}

//刪除數據元素的算法
int ListDelete(SqList &L,int i,ElemType &e)
{
 int j;
 if(i<1 || i>L.length)
  return 0;
 i--;
 e=L.data[i];
 for(j=i;j<L.length-1;j++)
  L.data[j]=L.data[j+1];
 L.length--;
 return 1;
}

//有序表的歸併算法
void Merge_SortedList(SqList L1,SqList L2,SqList& L3)
{
 int i=0,j=0,k=0;
 while(i<L1.length && j<L2.length)
 {
  if(L1.data[i]<L2.data[j])
  {
   L3.data[k]=L1.data[i];
   i++;k++;
  }
  else if(L1.data[i]>L2.data[j])
  {
   L3.data[k]=L2.data[j];
   j++;k++;
  }
  else
  {
   L3.data[k]=L1.data[i];
   i++;j++;k++;
  }
 }

 while(i<L1.length)
 {
  L3.data[k]=L1.data[i];
  i++;k++;
 }
 while(j<L2.length)
 {
  L3.data[k]=L2.data[j];
  j++;k++;
 }
 L3.length=k;
}

//遍歷順序表
void Traverse(SqList L)
{
 printf("Traversing...: ");
 for(int i=0;i<L.length;i++)
 {
  printf("%d ",L.data[i]);
 }
 printf("/n");
}

//2-2-10已知一個遞增有序表(incrementing orderly table)
//,現插入x使其仍然遞增
void insert_iot(SqList &L,ElemType x)
{
 int i=0,j;
 while(i<L.length && x>=L.data[i])
  i++;
 for(j=L.length-1;j>=i;j--)
  L.data[j+1]=L.data[j];
 L.data[i]=x;
 L.length++;
}

//2-2-11設計一算法,將順序表的所有元素逆置,要求
//算法複雜度爲O(1)
void reverse(SqList &L)
{
 int i;
 ElemType x;
 for(i=0;i<L.length/2;i++)
 {
  x=L.data[i];
  L.data[i]=L.data[L.length-i-1];
  L.data[L.length-i-1]=x;
 }
}

//2-2-12設計一算法,刪除所有值的x,
//要求空間複雜度O(1)
void delall(SqList& L,ElemType x)
{
 int i=0,j;
 //找到第一個
 while(i<L.length && L.data[i]!=x)
  i++;
 for(j=i+1;j<L.length;j++)
  if(L.data[j]!=x)
  {
   L.data[i]=L.data[j];
   i++;
  }
 L.length=i;
}

//2-2-12方法二
//算法複雜度爲O(n)
void delall2(SqList &L,ElemType x)
{
 int i=0,k=0;
 while(i<L.length)
 {
  if(L.data[i]==x)
   k++;
  else
   L.data[i-k]=L.data[i];
  i++;
 }
 L.length-=k;
}

//2-2-12 自己的方法
//算法不太好,另外將找到的結果先標記,
//再按照交換排序的方法前後交換
void delall_self(SqList &L,ElemType x)
{
 int i=0,j=0;
 while(i<L.length)
 {
  if(L.data[i]==x)
  {
   for(j=i;j<L.length-1;j++)
    L.data[j]=L.data[j+1];
   L.length--;
  }
  else
   i++;
 }
}

//2-2-13設計一算法,從給定的順序表L中刪除元素
//值在x到y(x<=y)的所有元素值,空間複雜度爲O(1)
void delallxy(SqList &L,ElemType x,ElemType y)
{
 int i=0,k=0;
 while(i<L.length)
 {
  if(L.data[i]>=x && L.data[i]<=y)
   k++;
  else
   L.data[i-k]=L.data[i];
  i++;
 }
 L.length-=k;
}

//2-2-14有一順序表L,其元素爲整型數據,設計一算法
//將所有小於0的整數放在前半部分,大於等於0的整數
//放在後半部分
void move(SqList &L)
{
 ElemType temp;
 int i=0,j=L.length-1;
 while(i<j)
 {
  while(i<j && L.data[i]<0)
   i++;
  while(i<j && L.data[j]>=0)
   j--;
  if(i<j)
  {
   temp=L.data[i];
   L.data[i]=L.data[j];
   L.data[j]=temp;
  }
 }
}

//2-2-15設計一算法從順序表中刪除重複的元素
//並使剩餘的元素間的相對次序保持不變
void delsame(SqList &L)
{
 //j記錄合格的元素,
 //i爲指示標
 //k輔助變量
 int i,j,k;
 if(L.length>0)
 {
  j=0;
  for(i=1;i<L.length;i++)
  {
   k=0;
   while(k<=j && L.data[k]!=L.data[i])
    k++;
   if(k>j)
   {
    j++;
    L.data[j]=L.data[i];
   }
  }
  L.length=j+1;
 }
}

//2-2-16用順序表表示集合,(如果有相同元素就不成立)
//設計一算法實現集合的求交集運算
void Intersection(SqList A,SqList B,SqList &C)
{
 int i,j,k=0;
 for(i=0;i<A.length;i++)
 {
  j=0;
  while(j<B.length && B.data[j]!=A.data[i])
   j++;
  if(j<B.length)
   C.data[k++]=A.data[i];
 }
 C.length=k;
}

//2-2-16自己的算法(主要是處理重複元素的情況)
void Intersection_self(SqList A,SqList B,SqList &C)
{
 int i=0,j=0,k=0,m=0;
 for(;i<A.length;i++)
 {
  m=0;
  while(m<i)
  {
   if(A.data[m]==A.data[i])break;
   m++;
  }
  if(m<i)continue;

  j=0;
  while(j<B.length && A.data[i]!=B.data[j])
   j++;
  if(A.data[i]==B.data[j])
  {
   C.data[k++]=A.data[i];
  }
 }
 C.length=k;
}

//2-2-17順序表表示集合,設計一算法實現
//集合的求並集運算
void Union(SqList A,SqList B,SqList &C)
{
 int i,j,k=0;
 for(i=0;i<A.length;i++)
  C.data[i]=A.data[i];
 C.length=A.length;
 for(i=0;i<B.length;i++)
 {
  j=0;
  while(j<A.length && B.data[i]!=A.data[j])
   j++;
  if(j==A.length)
   C.data[C.length+k++]=B.data[i];
 }
 C.length+=k;
}

//2-2-17自己的算法(處理元素重複的情況)
void Union_self(SqList A,SqList B,SqList &C)
{
 int i=0,k=0;
 ElemType temp;
 for(i=0;i<A.length+B.length-1;i++)
 {
  if(i<A.length)temp=A.data[i];
  else temp=B.data[i-A.length+1];
  for(k=0;k<C.length;k++)
  {
   if(temp==C.data[k])
    break;
  }

  if(k>=C.length)
  {
   C.data[k]=temp;
   C.length++;
  }
 }
}

//2-2-18順序表表示集合,設計一合適
//的求差集運算
void Difference(SqList A,SqList B,SqList &C)
{
 int i,j,k=0;
 for(i=0;i<A.length;i++)
 {
  j=0;
  while(j<B.length && B.data[j]!=A.data[i])
   j++;
  if(j==B.length)
   C.data[k++]=A.data[i];
 }
 C.length=k;
}

//2-2-18自己的算法
void Difference_self(SqList A,SqList B,SqList &C)
{
 int i=0,j=0,k=0,m=0;
 while(i<A.length)
 {
  j=0;
  while(j<i)
  {
   if(A.data[i]==A.data[j])break;
   j++;
  }
  if(j>=i)
  {
   k=0;
   while(k<B.length && B.data[k]!=A.data[i])
    k++;
   if(k>=B.length)
   {
    C.data[m++]=A.data[i];
   }
  }
  i++;
 }
 C.length=m;
}

//2-2-19已知順序表A、B,其中元素的個數
//分別爲m,n,若表中的數據均是遞增的,且
//這(m+n)個數據中沒有重複的
//(1)將兩表歸併,存於新表C中
//時間複雜度爲O(m+n)
void merge1(SqList A,SqList B,SqList &C)
{
 int i=0,j=0,k=0;
 while(i<A.length && j<B.length)
 {
  if(A.data[i]<B.data[j])
  {
   C.data[k]=A.data[i];
   i++;k++;
  }
  else
  {
   C.data[k]=B.data[j];
   j++;k++;
  }
 }
 while(i<A.length)
 {
  C.data[k]=A.data[i];
  i++;k++;
 }
 while(j<B.length)
 {
  C.data[k]=B.data[j];
  j++;k++;
 }
 C.length=k;
}

//(2)如果B的大小爲(m+n)個單元,是否可不利用順序表C
//而將合成的線性表存於順序表B中,設計此算法
//算法時間複雜度爲O(m*n)
void merge2(SqList A,SqList &B)
{
 int i=0,j=0,k;
    while(i<A.length)
 {
  if(A.data[i]>B.data[B.length-1])
  {
   B.data[B.length]=A.data[i];
   B.length++;i++;
  }
  else if(A.data[i]<B.data[j])
  {
   for(k=B.length-1;k>=j;k--)
    B.data[k+1]=B.data[k];
   B.data[j]=A.data[i];
   B.length++;
   i++;j++;
  }
  else j++;
 }
}

//(2)self
void merge2_2(SqList A,SqList &B)
{
 int i=0,j=0,k=0;
 while(i<A.length)
 {
  while(j<B.length && A.data[i]>=B.data[j])
   j++;
  if(j<B.length)
  {
   for(k=B.length;k>j;k--)
    B.data[k]=B.data[k-1];
   B.data[j]=A.data[i];
   B.length++;
   j++;
  }
  i++;
 }
}

//(3)設順序表A有m+n個元素,且前m個有序
//,後n個有序,設計一個算法使整個有序
//時間複雜度爲O(m*n)
void merge3(SqList &A,int m,int n)
{
 int i=0,j=m,k;
 ElemType tmp;
 while(j<A.length && i<j)
 {
  if(A.data[j]>A.data[j-1])
   break;
  else if(A.data[j]<A.data[i])
  {
   tmp=A.data[j];
   for(k=j-1;k>=i;k--)
    A.data[k+1]=A.data[k];
   A.data[i]=tmp;
   i++;j++;
  }
  else//找合適的位置插入
   i++;
 }
}

//(3)self 想用交換排序,其實和插入
//排序差不多,有序的情況還是插入排
//較好

int main()
{
 //std::cout<<1+1<<std::endl;
 SqList l,s,total;

 //初始化
 InitList(l);
 InitList(s);
 InitList(total);


 //插入
 ListInsert(l,1,1);
 ListInsert(l,2,1);
 ListInsert(l,3,2);
 ListInsert(l,4,4);

    //2-2-10測試
 //insert_iot(l,3);
 Traverse(l);

 //2-2-11測試
 //reverse(l);
    //printf("After reversing,the result is :/n");
 
 //2-2-12測試
 //delall(l,9);
 //delall2(l,9);
 //delall_self(l,9);
 //printf("After deleting,the result is :/n");

 //2-2-13測試
 //delallxy(l,7,9);
 //printf("After deleting,the result is :/n");

 //2-2-14測試
 //move(l);
 //printf("After moving,the result is :/n");

 //2-2-15測試
 //delsame(l);
 //printf("After deleting same elment,the result is :/n");

 //2-2-16測試
 //2-2-17測試
 //2-2-18測試
 //2-2-19測試
 ListInsert(s,1,2);
 ListInsert(s,2,3);
 ListInsert(s,3,4);

 printf("Traversing s: ");
 Traverse(s);

 //Intersection(l,s,total);
 //Intersection_self(l,s,total);
 //Union(l,s,total);
 //Union_self(l,s,total);
 //Difference(l,s,total);
 //Difference_self(l,s,total);
 //merge1(l,s,total);
    //merge2(l,s);
 merge2_2(l,s);
 //merge3(l,2,2);

 printf("Traversing total: ");
 Traverse(s);

 /*
 //有序表的歸併
 ListInsert(s,1,2);
 ListInsert(s,2,6);
 ListInsert(s,3,6);
 ListInsert(s,4,10);

 Merge_SortedList(l,s,total);
 printf("SqList l: ");
 for(int i=0; i<l.length;i++)
  printf("%d ",l.data[i]);
 
 printf("/nSqList s: ");
 for(i=0;i<s.length;i++)
  printf("%d ",s.data[i]);

 printf("/nSqList total: ");
 for(i=0;i<total.length;i++)
  printf("%d ",total.data[i]);

 printf("/n");

 //取元素
 int get,e;
 get=GetElem(l,1,e);
 if(get)
  printf("get first elment: %d/n",e);
 else
  printf("Error Get!");

 //刪除元素
 int del;
 del=ListDelete(l,2,e);
 if(del)
  printf("delete second elment: %d/n",e);
 else
  printf("Error Delete!");

 //查找元素
 int loc;
 loc=LocateElem(l,4);
 if(loc)
  printf("elment 4 locates at :%d/n",loc);
 else
  printf("Can't Find!/n");
 */

 return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章