CSAPP-lab0:C Programming Lab
本文最后更新于:2022年11月2日 晚上
队列的链表实现
用一个结构体来表示链表,定义如下:
1 |
|
- queue_t结构体中head、tail分别是指向list_ele_t类型的指针
- list_ele结构体中包含两个指针,分别指向char和list_ele类型
- 队列的数据结构如下所示:
实验要求
完成以下函数并通过评测系统:
1 |
|
queue_new
- 使用malloc在堆上给queue_t分配内存
- 将head和tail指针、size初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* @brief Allocates a new queue
* @return The new queue, or NULL if memory allocation failed
*/
queue_t *queue_new(void) {
// malloc:success return pointer to addr ; error return NULL
queue_t *q = malloc(sizeof(queue_t));
/* What if malloc returned NULL? */
if (q != NULL) {
q->head = NULL;
q->tail = NULL;
q->size = 0;
}
return q;
}
queue_free
- 使用free函数释放内存,注意到q->head->value和q->head都应该被free,如果只free了q->head->value会报内存泄露
1 |
|
queue_insert_head
- 在头部插入节点
- 使用malloc为新节点和新节点中的字符串分配空间,注意
sizeof(char) * (strlen(s) + 1)
语句 - 除了给节点、节点内的字符串分配空间外,不可以分配别的空间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43/**
* @brief Attempts to insert an element at head of a queue
*
* This function explicitly allocates space to create a copy of `s`.
* The inserted element points to a copy of `s`, instead of `s` itself.
*
* @param[in] q The queue to insert into
* @param[in] s String to be copied and inserted into the queue
*
* @return true if insertion was successful
* @return false if q is NULL, or memory allocation failed
*/
bool queue_insert_head(queue_t *q, const char *s) {
/* What should you do if the q is NULL? */
if (q == NULL)
return false;
list_ele_t *newh = (list_ele_t *)malloc(sizeof(list_ele_t));
if (newh == NULL)
return false;
/* Don't forget to allocate space for the string and copy it */
newh->value = (char *)malloc(sizeof(char) * (strlen(s) + 1));
newh->next = NULL;
/* What if either call to malloc returns NULL? */
if (newh->value == NULL) {
free(newh); // this is important
return false;
}
strcpy(newh->value, s);
// insert
if (q->head == NULL) // what if q->head ==NULL?
{
q->head = newh;
q->tail = newh;
q->size++;
} else {
newh->next = q->head;
q->head = newh;
q->size++;
}
return true;
}
queue_remove_head
- 将队列头结点删去,同时要使用strncpy将节点中的字符串复制保存下来
- 注意strncpy的用法,可以参考c++reference,字符串末尾要手动加\0
- 要同时free节点和节点内指向char的指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* @brief Attempts to remove an element from head of a queue
*
* If removal succeeds, this function frees all memory used by the
* removed list element and its string value before returning.
*
* If removal succeeds and `buf` is non-NULL, this function copies up to
* `bufsize - 1` characters from the removed string into `buf`, and writes
* a null terminator '\0' after the copied string.
*
* @param[in] q The queue to remove from
* @param[out] buf Output buffer to write a string value into
* @param[in] bufsize Size of the buffer `buf` points to
*
* @return true if removal succeeded
* @return false if q is NULL or empty
*/
bool queue_remove_head(queue_t *q, char *buf, size_t bufsize) {
/* You need to fix up this code. */
if (q == NULL || q->size == 0 || buf == NULL)
return false;
strncpy(buf, q->head->value, bufsize - 1); // max bufsize-1 bytes copied
buf[bufsize - 1] = '\0';
list_ele_t *temp = q->head;
if (q->size == 1) {
q->size--;
q->head = NULL;
q->tail = NULL;
if (temp->value != NULL)
free(temp->value);
free(temp);
} else {
q->size--;
q->head = q->head->next;
if (temp->value != NULL)
free(temp->value);
free(temp);
}
return true;
}
queue_size
- 要注意到返回值是size_t类型,所以要进行一次强制类型转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17/**
* @brief Returns the number of elements in a queue
*
* This function runs in O(1) time.
*
* @param[in] q The queue to examine
*
* @return the number of elements in the queue, or
* 0 if q is NULL or empty
*/
size_t queue_size(queue_t *q) {
/* You need to write the code for this function */
/* Remember: It should operate in O(1) time */
if (q != NULL)
return (unsigned long)q->size;
return (unsigned long)0;
}queue_reverse
- 使用三个指针,pre指针和iter指针用来改变节点的指向,next指针一直往后移动且试探是否下一个节点为null
- 绿色为被改变的节点指针的指向
- 红色表示每次循环这三个指针都要往后指
- 最后,队列的首位指针要调换
1 |
|
测评
1 |
|
结果
1 |
|
CSAPP-lab0:C Programming Lab
http://gls.show/p/3b50ff2c/