一、N皇后问题
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int place(int *paraSolution, int paraT) {
int j;
for (j = 1; j < paraT; j ++) {
if ((abs(paraT - j) == abs(paraSolution[j] - paraSolution[paraT])) || paraSolution[j] == paraSolution[paraT]) {
return 0;
}
}
return 1;
}
void backtracking(int *paraSolution, int paraN, int paraT) {
int i;
if (paraT > paraN) {
for (i = 1; i <= paraN; i ++) {
printf("%d ", paraSolution[i]);
}
printf("\n");
} else {
for (i = 1; i <= paraN; i ++) {
paraSolution[paraT] = i;
if (place(paraSolution, paraT) == 1) {
backtracking(paraSolution, paraN, paraT + 1);
}
}
}
}
void nQueen(int paraN) {
int i;
int solution[paraN + 1];
for (i = 0; i <= paraN; i ++) {
solution[i] = 0;
}
backtracking(solution, paraN, 1);
}
int main() {
nQueen(5);
return 0;
}
结果
1 3 5 2 4
1 4 2 5 3
2 4 1 3 5
2 5 3 1 4
3 1 4 2 5
3 5 2 4 1
4 1 3 5 2
4 2 5 3 1
5 2 4 1 3
5 3 1 4 2
注意:
(1)abs取绝对值,用来判断是否同一对角线上
(2)重点中的重点,back回溯函数,当满足一种情况时,就继续判断下去,不满足就回到上一个结点,十分便捷!!!
二、哈夫曼树的编码与解码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct HuffmanTree {
int weight;
int parent;
int LChild;
int RChild;
} HTNode, *HuffmanTreePtr;
void Select(HuffmanTreePtr tempPtr, int Length, int *LChild, int *RChild) {
int i, min1 = 99999, min2 = 99999;
*LChild = 0;
*RChild = 0;
for (i = 1; i <= Length; i ++) {
if (tempPtr[i].parent == 0) {
if (tempPtr[i].weight < min1) {
min2 = min1;
*RChild = *LChild;
min1 = tempPtr[i].weight;
*LChild = i;
} else if (tempPtr[i].weight < min2) {
min2 = tempPtr[i].weight;
*RChild = i;
}
}
}
}
HuffmanTreePtr InitHuffmanTree(int weight[], int Length) {
HuffmanTreePtr tempPtr = (HuffmanTreePtr)malloc(sizeof(HTNode));
int i, j;
for (i = 1; i <= Length; i ++) {
tempPtr[i].weight = weight[i - 1];
tempPtr[i].parent = 0;
tempPtr[i].LChild = 0;
tempPtr[i].RChild = 0;
}
j = Length + Length - 1;
for (; i <= j; i ++) {
tempPtr[i].weight = 0;
tempPtr[i].parent = 0;
tempPtr[i].LChild = 0;
tempPtr[i].RChild = 0;
}
int LChild, RChild;
for (i = Length + 1; i <= j; i ++) {
Select(tempPtr, i - 1, &LChild, &RChild);
tempPtr[i].weight = tempPtr[LChild].weight + tempPtr[RChild].weight;
tempPtr[LChild].parent = i;
tempPtr[RChild].parent = i;
tempPtr[i].LChild = LChild;
tempPtr[i].RChild = RChild;
}
return tempPtr;
}
void HuffmanTreeEncoding(HuffmanTreePtr tempPtr, int Length, char str[], char EncodResult[][100]) {
char code[100];
int i, codeLength, j, parent, k;
for (i = 1; i <= Length; i ++) {
codeLength = Length - 1;
int row = 1;
j = i;
parent = tempPtr[i].parent;
while (parent != 0) {
codeLength --;
if (tempPtr[parent].LChild == j) {
code[codeLength] = '0';
} else {
code[codeLength] = '1';
}
j = parent;
parent = tempPtr[parent].parent;
}
printf("%c的编码:", str[i - 1]);
EncodResult[i - 1][0] = str[i - 1];
for (k = 0; k < Length; k ++) {
if (code[k] == '0' || code[k] == '1') {
printf("%c", code[k]);
EncodResult[i - 1][row] = code[k];
row ++;
}
}
EncodResult[i - 1][row] = '\0';
printf("\n");
memset(&code, -1, Length);
}
}
void decodeHuffmanTree(char decode[], int length, char str[], char EncodResult[][100], int encodelength) {
int i, j, k;
for (i = 0; i < length; i ++) {
for (j = 0; j < encodelength; j ++) {
if (decode[i] == EncodResult[j][0]) {
k = 1;
for (; EncodResult[j][k] != '\0'; k ++) {
printf("%c", EncodResult[j][k]);
}
break;
}
}
}
printf("\n");
}
int calculateWeights(char decode[], int weight[], char str[], int length) {
int i, j;
int strlength = 1;
str[0] = decode[0];
weight[0] ++;
for (i = 1; i < length; i ++) {
for (j = 0; j < strlength; j ++) {
if (decode[i] == str[j]) {
weight[j] ++;
break;
}
}
if (j >= strlength) {
str[strlength] = decode[i];
weight[strlength] ++;
strlength++;
}
}
return strlength;
}
int findtree(HuffmanTreePtr tempPtr, char code, int location) {
if (code == '1') {
return tempPtr[location].RChild;
} else {
return tempPtr[location].LChild;
}
}
void DecodeString(HuffmanTreePtr tempPtr, char encode[], int encodelength, int treelength, char str[]) {
int i, j;
char theend[100];
int printlength = 0;
for (i = 0; i < encodelength; i ++) {
j = i;
int location = treelength;
while (tempPtr[location].LChild != 0) {
location = findtree(tempPtr, encode[j], location);
j ++;
}
i = j - 1;
if (j > encodelength) {
printf("Error,输入有误,无法解码");
return;
}
theend[printlength] = str[location - 1];
printlength ++;
}
printf("解码结果是:");
for (i = 0; i < printlength; i ++) {
printf("%c", theend[i]);
}
}
int main() {
int i, j;
int weight[100], strlength;
char decode[100], str[100];
int length;
HuffmanTreePtr tempPtr;
char EncodResult[100][100];
char encode[100];
int encodelength;
printf("请输入要解码的串:");
gets(decode);
length = strlen(decode);
for (i = 0; i < length; i ++) {
weight[i] = 0;
}
strlength = calculateWeights(decode, weight, str, length);
tempPtr = InitHuffmanTree(weight, strlength);
printf("哈夫曼树各结点值:\n");
for (j = 1; j <= strlength * 2 - 1; j ++) {
printf("%d ", tempPtr[j].weight);
}
printf("\n");
HuffmanTreeEncoding(tempPtr, strlength, str, EncodResult);
printf("编码结果:\n");
decodeHuffmanTree(decode, length, str, EncodResult, strlength);
printf("输入想解码的串:\n");
gets(encode);
encodelength = strlen(encode);
DecodeString(tempPtr, encode, encodelength, strlength * 2 - 1, str);
return 0;
}
其中一个输入结果
请输入要解码的串:ccseatrews
哈夫曼树各结点值:
2 2 2 1 1 1 1 2 2 4 4 6 10
c的编码:110
s的编码:111
e的编码:00
a的编码:010
t的编码:011
r的编码:100
w的编码:101
编码结果:
1101101110001001110000101111
输入想解码的串:
1101110001001110110000
解码结果是:cseatwre
总结与说明
读入一个字符串,统计每个字符出现的频率,然后构建哈夫曼树,算出每个字符的编码
读入一个新的01字符串,将其解码为字符,重点是构建树时,用数组的形势去理解
编码是,是从叶到根,倒叙的方式实现每个字符的编码
解码我的思路是,从根节点开始,读入1就前往右儿子结点,0就前往左儿子结点,直到没有下一个结点为止,再确定数组下标,对应字符数组,转换成字母