我无法在 C 中创建链表
I cannot create a linked list in C
基本上,对于我的作业,我需要实现代码来进行霍夫曼编码。为此,我需要将输入作为一个字符串,然后创建一个字符列表及其频率。当有新角色时,我需要创建一个新节点。我试过用 C 来做,但没有结果。当我尝试打印我的链接列表时,我根本无法获得任何输出。我相信我从一开始就没有创建列表。
我的 C 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct node {
char character;
int frequency;
struct node *next;
}head;
struct node *insert(int frequency, char character) {
struct node *newNode = malloc(sizeof(struct node));
newNode->character = frequency;
newNode->character = character;
return newNode;
}
void create_freq_list(struct node *initial, int str_size, char str[]) {
int i;
struct node *temp;
bool has_node;
for (i = 0; i < str_size; i++) {
temp = initial;
has_node = false;
while (temp->next != NULL) {
if (temp->character == str[i]) {
has_node = true;
temp->frequency++;
}
temp = temp->next;
}
if (has_node == false) {
while (temp->next != NULL) {
temp = temp->next;
if (temp->next == NULL) {
temp->next = insert(0, str[i]);
}
}
}
}
}
int main() {
struct node *temp;
char str[100];
gets_s(str, 100);
create_freq_list(&head, 100, str);
temp = &head;
while (temp->next != NULL) {
printf("'%c' : %d", temp->character, temp->frequency);
temp = temp->next;
}
getch();
exit(0);
}
您的代码中存在多个问题:
- 您对
head
节点的处理不正确:head
应定义为 node *
并且您应将其地址传递给 create_freq_list()
.
insert()
函数中有错别字:newNode->character = frequency;
- 您不应迭代字符串中超出空终止符的字符。
- 输出循环不正确:它应该迭代
while (head)
,而不是 while (head->next)
。按照编码,输出初始节点但无意义,最后一个节点被忽略。
这是修改后的版本:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char character;
int frequency;
struct node *next;
};
struct node *insert(int frequency, char character) {
struct node *newNode = malloc(sizeof(struct node));
if (newNode != NULL) {
newNode->frequency = frequency;
newNode->character = character;
}
return newNode;
}
void create_freq_list(struct node **headp, const char str[]) {
for (int i = 0; str[i]; i++) {
struct node **tailp = *headp;
struct node *temp;
while ((temp = *tailp) != NULL) {
if (temp->character == str[i]) {
temp->frequency++;
break;
}
tailp = &temp->next;
}
if (temp == NULL) {
*tailp = insert(1, str[i]);
}
}
}
int main() {
struct node *head = NULL;
char str[100];
gets_s(str, 100);
create_freq_list(&head, str);
for (struct node *temp = head; temp != NULL; temp = temp->next) {
printf("'%c': %d\n", temp->character, temp->frequency);
}
getch();
return 0;
}
请注意,使用包含 256 个元素的数组来计算字符频率要简单得多。
我可以提出一个变体,使用优秀的宏<sys/queue.h>
这不是一个标准的包含,但每个打包好的系统都应该有它。
好吧,它可能不如手动编写链表编码那么具有教学意义,但它更安全;-)
查看 man queue
(或 man LIST_INIT
)以查看功能。
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
typedef LIST_HEAD(listhead, entry) nodes_t;
typedef struct entry {
char character;
int frequency;
LIST_ENTRY(entry) entries;
} node_t;
void insert(nodes_t *list, char character) {
node_t *newNode = malloc(sizeof(node_t));
if (newNode != NULL) {
newNode->frequency = 1;
newNode->character = character;
LIST_INSERT_HEAD(list, newNode, entries);
}
}
node_t *get_node(nodes_t *list, char character) {
node_t *n;
LIST_FOREACH(n, list, entries)
if (n->character == character)
return n;
return NULL;
}
void create_freq_list(nodes_t *list, const char str[]) {
node_t *n;
for (int i = 0; str[i]; i++) {
n = get_node(list, str[i]);
if (n == NULL)
insert(list, str[i]);
else
n->frequency++;
}
}
void print_list(nodes_t *list) {
node_t *n;
LIST_FOREACH(n, list, entries)
printf("'%c': %d\n", n->character, n->frequency);
}
int main(int argc, char* argv[]) {
nodes_t list;
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
return -1;
}
LIST_INIT(&list);
create_freq_list(&list, argv[1]);
print_list(&list);
return 0;
}
基本上,对于我的作业,我需要实现代码来进行霍夫曼编码。为此,我需要将输入作为一个字符串,然后创建一个字符列表及其频率。当有新角色时,我需要创建一个新节点。我试过用 C 来做,但没有结果。当我尝试打印我的链接列表时,我根本无法获得任何输出。我相信我从一开始就没有创建列表。 我的 C 代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct node {
char character;
int frequency;
struct node *next;
}head;
struct node *insert(int frequency, char character) {
struct node *newNode = malloc(sizeof(struct node));
newNode->character = frequency;
newNode->character = character;
return newNode;
}
void create_freq_list(struct node *initial, int str_size, char str[]) {
int i;
struct node *temp;
bool has_node;
for (i = 0; i < str_size; i++) {
temp = initial;
has_node = false;
while (temp->next != NULL) {
if (temp->character == str[i]) {
has_node = true;
temp->frequency++;
}
temp = temp->next;
}
if (has_node == false) {
while (temp->next != NULL) {
temp = temp->next;
if (temp->next == NULL) {
temp->next = insert(0, str[i]);
}
}
}
}
}
int main() {
struct node *temp;
char str[100];
gets_s(str, 100);
create_freq_list(&head, 100, str);
temp = &head;
while (temp->next != NULL) {
printf("'%c' : %d", temp->character, temp->frequency);
temp = temp->next;
}
getch();
exit(0);
}
您的代码中存在多个问题:
- 您对
head
节点的处理不正确:head
应定义为node *
并且您应将其地址传递给create_freq_list()
. insert()
函数中有错别字:newNode->character = frequency;
- 您不应迭代字符串中超出空终止符的字符。
- 输出循环不正确:它应该迭代
while (head)
,而不是while (head->next)
。按照编码,输出初始节点但无意义,最后一个节点被忽略。
这是修改后的版本:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char character;
int frequency;
struct node *next;
};
struct node *insert(int frequency, char character) {
struct node *newNode = malloc(sizeof(struct node));
if (newNode != NULL) {
newNode->frequency = frequency;
newNode->character = character;
}
return newNode;
}
void create_freq_list(struct node **headp, const char str[]) {
for (int i = 0; str[i]; i++) {
struct node **tailp = *headp;
struct node *temp;
while ((temp = *tailp) != NULL) {
if (temp->character == str[i]) {
temp->frequency++;
break;
}
tailp = &temp->next;
}
if (temp == NULL) {
*tailp = insert(1, str[i]);
}
}
}
int main() {
struct node *head = NULL;
char str[100];
gets_s(str, 100);
create_freq_list(&head, str);
for (struct node *temp = head; temp != NULL; temp = temp->next) {
printf("'%c': %d\n", temp->character, temp->frequency);
}
getch();
return 0;
}
请注意,使用包含 256 个元素的数组来计算字符频率要简单得多。
我可以提出一个变体,使用优秀的宏<sys/queue.h>
这不是一个标准的包含,但每个打包好的系统都应该有它。
好吧,它可能不如手动编写链表编码那么具有教学意义,但它更安全;-)
查看 man queue
(或 man LIST_INIT
)以查看功能。
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
typedef LIST_HEAD(listhead, entry) nodes_t;
typedef struct entry {
char character;
int frequency;
LIST_ENTRY(entry) entries;
} node_t;
void insert(nodes_t *list, char character) {
node_t *newNode = malloc(sizeof(node_t));
if (newNode != NULL) {
newNode->frequency = 1;
newNode->character = character;
LIST_INSERT_HEAD(list, newNode, entries);
}
}
node_t *get_node(nodes_t *list, char character) {
node_t *n;
LIST_FOREACH(n, list, entries)
if (n->character == character)
return n;
return NULL;
}
void create_freq_list(nodes_t *list, const char str[]) {
node_t *n;
for (int i = 0; str[i]; i++) {
n = get_node(list, str[i]);
if (n == NULL)
insert(list, str[i]);
else
n->frequency++;
}
}
void print_list(nodes_t *list) {
node_t *n;
LIST_FOREACH(n, list, entries)
printf("'%c': %d\n", n->character, n->frequency);
}
int main(int argc, char* argv[]) {
nodes_t list;
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
return -1;
}
LIST_INIT(&list);
create_freq_list(&list, argv[1]);
print_list(&list);
return 0;
}