/************************************************************************/
/* @author lynnbest
問題1:順序表操作的複習
目標:將一個順序表分拆為兩個部分,左邊>=0,右邊小於0
exp:
input:-7,0,5,-8,9,-4,3,-2
ouput: 3,0,5,9,-8,-4,-7,-2
思路:採用分治的方法
從兩頭開始分別遍歷,設兩個計數器i,j左邊遍歷時,遇到>=0的跳過,<0停止。
右邊正好相反,遇到小於0跳過,>=0停止,然後此時交換兩個
指,然後繼續下一輪,直到i>j為止
*/
/************************************************************************/
#include <stdio.h>
void ChangePlace(int *a,int length);
void main()
{
int a[]={-7,0,5,-8,9,-4,3,-2,7,11,-3};
int length=sizeof(a)/sizeof(a[0]);
printf("改變之前:\n");
for(int i=0;i<length;i++)
printf("%4d",a[i]);
printf("\n");
ChangePlace(a,length);
printf("改變之後:\n");
for(i=0;i<length;i++)
printf("%4d",a[i]);
printf("\n");
}
/*void ChangePlace(int *a,int length) //計數器實現
{
int i=0,j=length-1,temp;; //陣列兩個首尾指標
//開始換位
while(i<=j)
{
while(a[i]>=0) //從左邊開頭查詢第一個<0的數
i++;
while(a[j]<0) //從右邊開頭查詢第一個>=0的數
j--;
//然後交換兩個位置的值
temp=a[i];
a[i]=a[j];
a[j]=temp;
i++; //i,j移動
j--;
}
}
*/
void ChangePlace(int *a,int length) //指標實現
{
int *left=a,*right=a+length-1,temp;
while(left<=right)
{
while(*left>=0) //<0停止
left++;
while(*right<0) //>=0停止
right--;
temp=*left;
*left=*right;
*right=temp;
left++;
right--;
}
}
/************************************************************************/
/* 問題2:線性表的就地逆置
所謂就地逆置就是在不佔用額外的儲存空間下,達到的效果
1. 順序儲存
對於陣列儲存而言就是將最後一個元素與第一個元素交換,第二個元素與倒數第二個交換
依次類推,比較 n/2次。
對於次數的操作,我有時候會暈,C陷進與缺陷中提到不對稱的邊界書寫,差值正好代表元素的個數
for(i=0;i<5;i++) 那麼要遍歷5次=5-0
2.鏈式儲存
*/
/************************************************************************/
#include <stdio.h> //線性表的順序儲存逆置
void InverseSeqlist(int *a,int length);
void printflist(int *a,int len);
void main()
{
int a[]={-7,0,5,-8,9,-4,3,-2,7,11,-3};
int length=sizeof(a)/sizeof(a[0]);
printf("之前\n");
printflist(a,length);
InverseSeqlist(a,length);
printf("之後\n");
printflist(a,length);
}
void InverseSeqlist(int *a,int length)
{
int temp;
for(int i=0;i<length/2;i++)
{
temp=a[length-1-i];
a[length-1-i]=a[i];
a[i]=temp;
}
}
void printflist(int *a,int len)
{
for(int i=0;i<len;i++)
printf("%3d",a[i]);
printf("\n");
}