//线性表第一题
bool Del(SqList &L,int &min){
if(L.length == 0){ //表为空返回false
return false;
}
int min = L.data[0]; //假设第一个元素的值最小
int pos; //最小元素的位置
for(int i = 0; i < L.length; i++){
if(L.data[i] < min){ //如果线性表中有比min更小的,交换它们
swap(min, L.data[i]);
pos = i; // 交换一次,记录一次最小元素的位置
}
}
L.data[pos] == L.data[Length - 1]; //那个位置用最后一个元素补充
L.length--;
return true;
}
/*双指针 反向
第二题
*/
void Reverse(SqList &L){
int left, right; //指向表头表尾的指针
for(int left = 0; right = L.length - 1; left < right; left ++, right--){ //两头指针向中间移动,如果前面的比后面的大,交换它们
if(L.data[left] < L.data[right]){
swap(L.data[left], L.data[right]);
}
}
}
//第三题 双指针 同向
void DelX(SqList &L, int x){
int i, j = 0; //初始化同向指针的位置为0
while(j < L.length){
if(L.data[j] != x){ //如果 J 所指的值不等于x ,就让两个指针同时向前移动 ,否则只让 J向前移动,最后返回 i
L.data[i++] = L.data[j++];
}else{
j++;
}
}
return i;
}
//第四题
void DelXs(SqList &L, int s, int t){
if(s < 0 && t > L.length && t < s){ //位置不合法
return false;
}
int i, j;
for(int i = 0; i < L.length - 1; i++){
if(L.data[i] > s) //寻找值大于s的第一个元素
int left = i;
}
for(int j = 0; j < L.length - 1; j++){
if(L.data[j] > t) //寻找值大于t的第一个元素
int right = j;
}
for(;j < L.length; i++, j++){ //前移,填补删除元素的位置
L.data[i] = L.data[j];
}
return true;
}
//第六题 双指针(同向)
void RemoveDup(SqList &L){
int i, j = 0; //初始化同向双指针的位置
while(j < L.length){
if(i == 0 || L.data[j] != L.data[i - 1]) //如果发现重复元素, 让 j ++ ,如果没有发现重复元素,让 i和 j 都 ++
L.data[i++] = L.data[j++];
else
j++;
}
return i;
}
//第七题 归并排序思想 (不多解释)
bool Merge(SqList A, SqList B, SqList &C){
int i, j, k = 0;
if(A.length + B.length > C.Maxsize)
return false;
while(i < A.length && j < B.length){
if(A.data[i] <= B.data[j]){
C.data[k++] = A.data[i++];
}else{
C.data[k++] = B.data[j++];
}
}
while(i < A.length){
C.data[k++] = A.data[i++];
}
while(j < B.length){
C.data[k++] = B.data[j++];
}
C.length = k;
return true;
}
//第八题(妙)
//先交换整个线性表,再对前n个和后m个使用逆置算法
void REVS(SqList &A, int left, int right){
int left, right;
for(int left = 0; right = L.length - 1; left < right; left ++, right--){
swap(L.data[left], L.data[right]);
}
}
void change(SqList& A){
REVS(A, 0, m + n - 1); //将整个表反转 表 1 长度为 m ,表2长度为 n
REVS(A, 0, n - 1); //将在前面的表2逆转
REVS(A, n, m + n - 1); //m + n - 1中包含了 m 个元素
}
//第九题
void Search(int A[], int x){ //先使用二分查找查找元素x
int low = 0;
int high = L.length - 1;
int mid;
while(low <= high){
mid = (low + high) / 2;
if(A[mid] > x){
high = mid - 1;
}else if(A[mid] < x){
low = mid + 1;
}
}
if(A[mid] == x && mid != n - 1) //若交换后一个元素与x值相等,则不存在与其后继交换的操作
swap(A[mid],A[mid + 1]);
if(low > high){
for(int i = n -1; i > high; i--){ //查找失败 , 插入x
A[i + 1] = A[i];
A[i + 1] = x;
}
}
}
//第十题
//把数组看成2部分,A中元素再前面,A中有P个元素,B中元素在后面,左移P个位置, 相当于将A 、B逆置 ,再整体取逆 ( AB --> BA )
void Reverse1(int R[ ], int r, int l){
for(int i = 0; i < l - r; i++){
swap(R[i + r], R[l - i]);
}
}
void MoveLeft(int R[], int n, int p){
Reverse1(R, 0, p - 1);
Reverse1(R, p, n - 1);
Reverse1(R, 0, n - 1);
}
// 第十一题
//使用归并排序的思想进行合并数组,再找出中位数,优化:仅进行判断,不进行排序,仅按顺序进行访问,访问 [L / 2]后为所求降低空间复杂度
void Merge(int A[], int B[], int &C[]){
int i, j, k = 0;
while(L1.data[i] < L2.data[j]){
L3.data[k++] = L1.data[i++];
}
while(L1.data[i] > L2.data[j]){
L3.data[k++] = L2.data[j++];
}
while(i < L1.length){
L3.data[k++] = L1.data[i++];
}
while(j < L2.length){
L3.data[k++] = L2.data[j++];
}
}
// 求出中位数
int Mid(int C[]){
int mid;
int n = L.length;
if(n % 2 == 0){
mid = (C[n / 2] + C[n / 2 - 1] ) / 2;
}else{
mid = C[(n - 1)/ 2];
}
return mid;
}
//第十二题
int MajorElm(int A[],int n){
int tmp = A[0];
int count;
for(int i = 1; i <= n; i++){
if(A[i] == tmp)
count++;
//记录下一个元素的时候先要清空count
}else{ //处理的不是主元素的情况
if(count > 0)
count--;
else{ //妙啊,这里统计的count不是最终的count值,遇到的下一个整数 = tmp ,计数器加一 ,遇到的下一个整数 != tmp 计数器减一
tmp = A[i];
count = 1;
}
}
if(count > 0){ //统计主元素实际出现的次数
count = 0;
for(int i = 0; i < n; i++){
if(A[i] = tmp)
count++;
}
}
if(count > n / 2)
return tmp;
else
return -1;
}
//第十三题
//采用空间换时间的策略
int MaxPositiveNum(int A[], int n){
int *B;
B = (int*)malloc(sizeof(int) * n);
memset(B, 0, sizeof(int) * n);
for(int i = 0; i < n; i++){ //标记数组B
if(A[i] > 0 && A[i] < n)
B[A[i] - 1] = 1;
}
for(int i = 0; i < n; i++){
if(B[i] == 0)
break;
}
return i + 1;
}