1: /*
2: *discription:给定一组数,将零全部排到最后,将非零元素排在最前,华为面试
3: *autor:justinzhang
4: *Email:uestczhangchao@gmail.com
5: *Established:2011年2月8日21:13:47
6: *Revised1:2011年4月24日15:57:22
7: *Revised2:2011年5月10日15:21:54,受到算法导论快速排序的启发,(p85)
8: * 利用快速排序中用来寻找支点的算法来完成任务
9: */
10:
11:
12: #include <iostream>
13: using namespace std;
14: #define arraysize(type, name) (sizeof(name) / sizeof(type))
15:
16:
17: /*http://www.iteye.com/topic/684511 这个帖子是讲如何将0元素移动到最前面,非零元素移动到最后面的*/
18:
19: /*
20: *nonezerofirst()和zerofirst()采用了不同的思想,具体参见源代码了.
21: *
22: */
23:
24:
25: /* 打印数组里的元素*/
26: void display(int data[], int len)
27: {
28: for(int i=0; i<len; i++)
29: cout << data[i] << endl;
30: }
31:
32: /*用算法导论中快速排序算法找支点的思想来完成将0元素集中到最前面
33: *使用这个思想可以解决把具有某一性质(0,非零,负数,正数等等)
34: *的元素移动到数组的末尾或者最前面的问题
35: */
36:
37: void quickmove_zerofirst(int data[], int len)
38: {
39: int i = -1;
40:
41: /*data中元素下标从0开始,故倒数第1个元素的下标为len-1;
42: *从左向右扫描数组,如果发现0就与最前边由i记录的位置处元素交换
43: */
44: for(int j=0; j<=len-1;j++)
45: {
46: if(data[j]==0)
47: {
48: i++;
49: data[j] = data[i];
50: data[i] = 0;
51: }
52: }
53: cout << "in quickmove_zerofirst" << endl;
54: display(data,len);
55: cout << "end of quickmove_zerofirst" << endl;
56: }
57:
58:
59: /*用算法导论中快速排序算法找支点的思想来完成将0元素集中到最后面*/
60: void quickmove_zerolast(int data[], int len)
61: {
62: //data中元素下标从0开始,故倒数第1个元素下一个元素为len,
63: //此处为刚好为数组越界的位置,这样做主要是为了方便循环的处理的统一
64: //i记录的是最右边0元素序列的最左边位置
65: int i=len;
66: for(int j=len-1; j>=0;j--)
67: {
68: //如果在扫描过程中发现了0元素,就把它交换到数组右边0元素序列的最左边
69: if(data[j]==0)
70: {
71: i = i-1;
72: data[j] = data[i];
73: data[i] = 0;
74: }
75: }
76: cout << "in quickmov_zerolast" << endl;
77: display(data,len);
78: cout << "end of quickmov_zerolast" <<endl;
79: }
80:
81:
82:
83:
84: /*
85: *该函数将0元素移动到数据的最前面,非零元素移动到队列的最后面。
86: *实现方法是:从数组的最后一个元素向前扫描,记住非零元素串最右边的位置,
87: *程序中用high来表示,结束扫描的时候[0,high]之间的数全部清零就可以完成任务。
88: */
89: void zerofirst(int data[], int len)
90: {
91: //自右向左扫描,将所有非零元素紧凑到右侧
92: int low, high;
93: for(low = len -1,high = low; low >=0; low--)
94: {
95: if(data[low]!=0)
96: {
97: data[high] = data[low];
98: high--;//更新紧凑序列的最左侧元素
99: }
100: }
101:
102: for(;high>=0; high--)
103: {
104: data[high] = 0;
105: }
106: cout << "in zero first" << endl;
107: display(data, len);
108: cout << "end of zero first" << endl;
109:
110: }
111:
112: void nonzerofirst(int data[], int len)
113: {
114: //自左向右扫描,将非零元素紧凑到最左边
115: int j = 0;
116: for (int i = 0; i < len; i++) {
117: //加入下面的判断是为了记录下非零元素串最右边的位置
118: if(data[i] != 0)
119: j++; //更新紧凑序列最右边的元素位置
120: if (data[i] == 0 && i != len - 1 && data[i + 1] != 0) {
121: data[j++] = data[i + 1];
122: data[i + 1] = 0;
123: }
124: }
125: cout << "non zero first " << endl;
126: display(data, len);
127: cout << "end of non zero first " << endl;
128: }
129:
130: int main()
131: {
132: int a[] = { 4,4,0, 4, -7, 2, 160, 0,0,0,0, 34, 21, 0, 19, 107 };
133: int j = 0;
134: int tmp = arraysize(int, a);
135: cout << sizeof(a) << endl;
136: cout << "sizeof(a)" << tmp << endl;
137: quickmove_zerofirst(a,tmp);
138: quickmove_zerolast(a,tmp);
139:
140: zerofirst(a, tmp);
141: nonzerofirst(a, tmp);
142: system("pause");
143: }