-------------------------------------
典型例题 29:C++问题---Zigzag数组输出
-------------------------------------
1 /**
2 * 得到如下样式的二维数组
3 * zigzag(jpeg编码里取象素数据的排列顺序)
4 *
5 * 0, 1, 5, 6,14,15,27,28,
6 * 2, 4, 7,13,16,26,29,42,
7 * 3, 8,12,17,25,30,41,43,
8 * 9,11,18,24,31,40,44,53,
9 * 10,19,23,32,39,45,52,54,
10 * 20,22,33,38,46,51,55,60,
11 * 21,34,37,47,50,56,59,61,
12 * 35,36,48,49,57,58,62,63
13 */
14 #include
15 #include
16 #include
17
18 using namespace std;
19
20 int zigzag1(int N)
21 {
22 int s, i, j;
23 int squa;
24 /* 分配空间 */
25 int **a = (int **)malloc(N * sizeof(int *));
26 if(a == NULL)
27 return 0;
28 for(i = 0; i < N; i++) {
29 if((a[i] = (int*)malloc(N * sizeof(int))) == NULL) {
30 while(--i>=0)
31 free(a[i]);
32 free(a);
33 return 0;
34 }
35 }
36 /* 数组赋值 */
37 squa = N*N;
38 for(i = 0; i < N; i++)
39 for(j = 0; j < N; j++) {
40 s = i + j;
41 if(s < N)
42 a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);
43 else {
44 s = (N-1-i) + (N-1-j);
45 a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));
46 }
47 }
48 /* 打印输出 */
49 for(i = 0; i < N; i++) {
50 for(j = 0; j < N; j++)
51 printf("%-6d", a[i][j]);
52 printf("/n");
53 }
54 return 0;
55 }
56
57 void zigzag2(int n)
58 {
59 int **a =(int**) malloc(n*sizeof(int *)); //分配空间
60
61 if(NULL == a)
62 return ;
63 int i;
64 for(i = 0; i < n; i++) {
65 if((a[i] =(int*) malloc(n * sizeof(int))) == NULL) {
66 while(--i>=0)
67 free(a[i]);
68 free(a);
69 return;
70 }
71 }
72
73 bool flag = false; //这个标志位用来判断是从45度角生成还是225度角生成
74 int count = 0;
75 for(i=0; i
77
78 if(flag)
79 {
80 for(int r = 0; r<=i; r++)
81 {
82 a[r][i-r] = count;
83 count++;
84 }
85 flag = false;
86 }
87 else
88 {
89 for(int r = i; r>=0; r--)
90 {
91 a[r][i-r] = count;
92 count++;
93 }
94 flag = true;
95 }
96 }
97 for(i=n-1; i>=0; i--) //生成的是下半部分的数据
98 {
99 if(flag)
100 {
101 for(int r = 0; r<=i-1; r++)
102 {
103 int r1 = n-i+r; //代表当前行
104 int c1 = 2*n-i-1-r1; //代表当前列
105 a[r1][c1] = count;
106 count++;
107 }
108 flag = false;
109 }
110 else
111 {
112 for(int r = i-1; r>=0; r--)
113 {
114 int r1 = n-i+r;
115 int c1 = 2*n-i-1-r1;
116 a[r1][c1] = count;
117 count++;
118 }
119 flag = true;
120 }
121 }
122 for(int r = 0; r
124 for(int c=0; c
126 printf("/n");
127 }
128 }
129
130 int main()
131 {
132 int N;
133 scanf("%d", &N);
134 zigzag1(N);
135 cout<<"-------------------"<
137 return 0;
138 }
----------------------------
$ ./a.out
4
0 1 5 6
2 4 7 12
3 8 11 13
9 10 14 15
----------------------------
0 1 5 6
2 4 7 12
3 8 11 13
9 10 14 15
----------------------------
--------------------------
知识点:
( 1 )算法 zigzag1 ()利用了沿 45 度线,数组下标 i + j 成 0 , 1 , 2 , 3 , ... 递增!并且
利用下标与其值的对应关系得出数组元素的值;
( 2 )算法 zigzag2 ()直接利用 zigzag 矩阵的特点进行编程实现!浅显易懂!特别注意那个
flag = false ;为是否为 225 度角度( true : 225 , false : 45 )