コンパイラ環境:対
言語:C / C ++
テーブルオーダー2つの分類:**(1)静的割り当て:データのアレイを格納するには、(2)動的割り当て:ポインタデータは、実行時に割り当てられ、記憶されます。
注:関数の戻り値はブール値(真\偽)の.cppで終了するC ++のもの、です。C言語は文句を言うでしょう。
1. 以下の二つの構造は以下のとおりです。
#define MaxSize 50
#define InitSize 50 //动态分配开辟的大小
typedef int ElemType;
//静态分配 数组形式
typedef struct{
ElemType data[MaxSize];
int length;
}Sqlist_s; //_s表示static
//动态分配 指针形式
typedef struct{
ElemType *data;
int length; //当前数据的长度
int Max_Size;//当前空间课容纳的最大长度
}Sqlist_d; //_d表示dynamic
以下は、静的割当データの関数で
初期化されていない場合、長さの乱数を初期化2.割り当てられていません。効果判定バック機能。
void ListInit(Sqlist_s &L)
{
L.length=0;
}
3.挿入操作(ヘッダ、挿入位置、挿入素子)
注:私はグループインデックス(ゼロ)のインデックスであり、iは論理(1つの開始)上の場所を参照する場合、私はi = 1。
時間の複雑さ:
//(1)插入操作(表头,插入位置,插入元素)
bool ListInsert(Sqlist_s L, int i, ElemType e)
{
if( i<0 || i>L.length) //判断i的位置是否有效
return false;
if( L.length >= MaxSize) //数组存储空间是否已满
return false;
for( int j=L.length; j>=i;j--) //后移为i位置让出空间
{
L.data[j]=L.data[j-1];
}
L.data[i]=e;
L.length++;
return true;
}
4.削除操作(ヘッダ、消失位置、保存削除要素)
時間計算:
コード:
//(2)删除操作
bool ListDelete(Sqlist_s &L , int i, ElemType &e)
{
if(i<0 || i>=L.length) // 下标在0 - length-1之间 i为下标
return false;
e=L.data[i];
for(int j=i+1; j<L.length;j++) //从i+1位置开始前移
L.data[j-1]=L.data[j];
L.length--;
return true;
}
5.値(シーケンシャルサーチ)を検索:L値の最初の要素eの要素、そのインデックスに戻りを見つけます。
時間計算:
//(3)按值查找(顺序查找):找第一个e,成功返回下标,失败返回0
int LocateElem(Sqlist_s L, ElemType e)
{
for(int i=0; i<L.length;i++)
{
if(L.data[i] == e)
return i;
}
return 0;
}
void show(Sqlist_s &L)
{
for(int i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
6.配列表の他の操作(上記基本動作以下、主に嘘が拡張演算である)
(1)テーブルの長さを検索し、検索ビット
//求表长
int GetLength(Sqlist_s L)
{
return L.length;
}
//按位查找:找到i位置的元素
bool GetElem(Sqlist_s L,int i,ElemType &e)
{
if(i<0 || i>=L.length) //判断i位置是否正确
return false;
e=L.data[i];
return true;
}
void show(Sqlist_s &L)
{
for(int i=0;i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
}
(2)は、最後の値充填位置、削除の戻り値を削除する(一意と仮定して)テーブルの最小の要素を削除します
//删除表中的最小元素,最后一个值填补,返回删除的值
bool Del_Min(Sqlist_s &L , ElemType &e)
{
if(L.length == 0) //表空退出
return false;
int pos =0; //表不为空 位置和最小的元素默认为0号位置
e = L.data[0];
for(int i=1;i<L.length;i++) //遍历比较找到最小的数,和最小数的位置
{
if(L.data[i] < e)
{
e = L.data[i];
pos = i;
}
}
L.data[pos] = L.data[L.length-1]; // 最后一个数填补删除的位置
L.length--; //长度减一 (容易遗漏)
return true;
}
(3)//空間複雑性O(1)配置順序テーブル逆である
アルゴリズム:[長-1-i]は配列表データの前半[i]は、後者のデータを入れ替え。すなわち、交換長/ 2回。
//用空间复杂度为O(1)来逆置顺序表
void Reverse(Sqlist_s &L)
{
if(L.length<1) //0 1 不用逆置
return;
ElemType temp;
for(int i=0; i< L.length/2; ++i) //用i 位 和lengh-1-i 对应互换
{
temp = L.data[i];
L.data[i] = L.data[L.length-1-i];
L.data[L.length-1-i]=temp;
}
}
(4)配列表の全てを削除は、x回必須の要素である:時間O(N)スペースO(1)(二つの方法)
①アイデア:K iがスクラッチであり、走査、k個のパッシブ、アクティブI一方、私xは位置kに置かれていない番号、k個の下降見つけた後、次の番号は、次の割り当てXを待っていない追加します。
//(8)删除顺序表中所有值为x次元素 要求:时间O(n) 空间 O(1)
void Del_x_1(Sqlist_s &L ,ElemType x)
{
//第一种用k记录不是x的元素个数
int k=0;
for(int i=0;i<L.length;i++)
{
if(L.data[i] != x)
{
L.data[k] = L.data[i];
k++;
}
}
L.length = k;
}
②アイデア:K統計は、要素xの数であり、kがインクリメントされる見つけます。要素iがxは満たされていない場合、前部要素は、x kは、前進位置をKです。
void Del_x_2(Sqlist_s &L , ElemType x)
{
//第二种k记录的是x的元素个数
int k=0;
for(int i=0;i<L.length;i++)
{
if(L.data[i] == x)
k++;
else
L.data[i-k]=L.data[i];
}
L.length=L.length-k;
}
(5)順 S <Tシーケンシャルリストの指定された値との間のすべての要素を削除する。
アルゴリズム:1.見出さSより大きいか添字X Iの最初の値に等しいです 2見つかった最初の添字jはtの値よりも大きいです。戻るjから転送します。
//(9)删除给定值s<t之间的所有元素
bool Del_s_t(Sqlist_s &L, ElemType s,ElemType t)
{
if(s>=t || L.length==0)
return false;
int i=0;
int j=0; //函数体要用到i j所以不要在for里面定义,出了for就没有了
for(i=0;i<L.length;i++) //找到第一个大于等于s的i
{
if(L.data[i] >= s)
break;
}
if( i == L.length )
return false;
for(j=i;i<L.length;j++) //找出第一个大于t的j
{
if(L.data[j] > t)
break;
}
for(;j<L.length;i++,j++) //j后面的数前移 第一个位置为i
L.data[i]=L.data[j];
L.length = i;
return true;
}
(6)障害以下のように、上記比較対象
//(10)无序顺序表中删除在s<t的数
bool Del_s_t2(Sqlist_s &L, ElemType s, ElemType t)
{
if(s> t|| L.length == 0 )
return false;
int k=0;
for(int i=0; i<L.length;i++)
{
if(L.data[i]>=s&&L.data[i]<=t) //k来记录当前在范围内的个数 是k+1
k++;
else
L.data[i-k]=L.data[i]; //否往前移动当前k个位置
}
L.length=L.length-k;
return true;
}
(7)は、テーブル内の値の順序付きシーケンスが、すべての値が異なっているように、すべての重複する要素を削除します
//(11)有序顺序表中删除所有值重复的元素,使所有值均不同
bool Delete_Same(Sqlist_s &L)
{
if(L.length == 0)
return false;
int i=0;
int j=0;
for(i=0,j=1;j<L.length;j++) //找到和i位置不同的数 就放到i+1处 i后移一位
{
if(L.data[i] != L.data[j])
L.data[++i] = L.data[j];
}
L.length = i+1; //i是从0开始 表示的是数组下标
return true;
}
(8)は、2つのシーケンステーブルを注文新しいシーケンステーブルに注文し、新しい配列を返します
//(12)两个有序顺序表合并为一个新的有序顺序表,并返回新的顺序表
bool Merge(Sqlist_s A, Sqlist_s B, Sqlist_d &C)
{
if(A.length + B.length > C.Max_Size)
return false;
int i=0; //记录A的位置
int j=0; //记录B的位置
int k=0; //记录C的位置
while( i<A.length && j<B.length ) //AB同时遍历 直到有一个先遍历完
{
if(A.data[i]<B.data[j]) //判断当前i j所指的位置谁小 谁放到C的k位置
C.data[k++]=A.data[i++];
else
C.data[k++]=B.data[j++];
}
while( i<A.length ) //总有一个先遍历完,剩下的直接贴到C的后面即可
C.data[k++]=A.data[i++];
while( j<B.length )
C.data[k++]=B.data[j++];
C.length=k;
return true;
}
(9)A [M + N] mは線形の長さであり、nは第2のリニアテーブルの長さである2つのテーブルが位置を交換
typedef int DataType;
void ReverseA( DataType A[],int left ,int right ,int arraySize)
{
if( left >= right || right >arraySize)
return;
int mid =(left +right)/2; //逆置次数为总数的一半
DataType temp;
for(int i=0;i<=mid -left;i++) // 以left为起始0位置 纸上画图判断是否需要等号
{
temp=A[left+i];
A[left+i] = A[right-i];
A[right-i] = temp;
}
}
//(13)A[m+n]中0-m是第一个线性表 ,m-n是第二个线性表,将两个表位置互换
void Exchange( DataType A[],int m ,int n,int arraySize)
{
ReverseA( A,0,m+n-1,arraySize); //全部逆置
ReverseA( A,0,n-1,arraySize); //逆置N的线性表
ReverseA( A,n,m+n-1,arraySize); //逆置m的线性表
}
(10)バイナリ検索テーブルXの順序付けられたシーケンス、およびその後の交換を見つけ、対応する線形テーブルの位置や秩序が見つからないaddが
//(14)有序顺序表折半查找x,找到则和后继交换,没有找到则添加相应位置使线性表还是有序的
void SearchAndExchangeorInsert(ElemType A[] ,ElemType x,int length)
{
int low = 0;
int high = length-1;
int mid;
while(low<=high) //折半查找 要么mid==x则退出循环进行交换,要么low>high退出循环进行插入
{
mid=(low+high)/2;
if(A[mid] == x)
break;
else if( A[mid] < x )
low=mid+1;
else
high=mid-1;
}
if(A[mid] == x && mid!= length-1) //找到的情况下
{
ElemType temp = A[mid];
A[mid] = A[mid]+1;
A[mid+1] = temp;
}
if(low > high) //没有找到的情况下
{
for(int i=length-1;i > high;i--)
A[i+1] = A[i];
A[high+1]=x;
}
}