/************************************************************************/ /* @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"); }