我是C的新手,我正在尝试创建一个函数来反转链表,只将List本身作为参数传递。这可以不将节点作为参数传递吗?
到目前为止,这是我的代码,我知道它无法正常工作,因为我无法弄清楚如何在列表的其余部分进行递归调用。
typedef struct {
node_t *head;
node_t *tail;
} LL_t;
typedef struct _node {
int data;
struct _node *next;
} node_t;
这里也是我的类型定义。
tail -200 FILENAME | grep CYP2C | awk '{ print "chr10\t",$2,"\t",$1}' | sed 's/10://g'
答案 0 :(得分:2)
您可以使用简单的循环反转列表,不需要递归并且给出您的API,这是不合适的。
以下是您的功能的修改版本:
void reverse(LL_t *L) {
node_t *prev = NULL;
node_t *curr = L->head;
L->tail = curr;
while (curr != NULL) {
node_t *next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
L->head = prev;
}
如果您需要使用递归,则可以测试列表是空的还是仅限于单例并且不执行任何操作,否则删除head元素,反转结果列表并将元素追加到末尾:
void reverse(LL_t *L) {
if (L->head != L->tail) {
/* at least 2 elements */
node_t *node = L->head;
L->head = node->next;
node->next = NULL;
reverse(L);
L->tail = L->tail->next = node;
}
}
请注意,如果列表太长,reverse
将递归太多次并导致堆栈溢出,则此递归方法可能会有未定义的行为。
答案 1 :(得分:1)
struct node {
int value;
struct node* next;
};
在常量堆栈空间中运行的非递归定义:
void reverse(struct node** ptr) {
struct node* prev_ptr;
struct node* node_ptr;
if (prev_ptr = * ptr) {
node_ptr = prev_ptr -> next;
prev_ptr -> next = NULL;
while (node_ptr) {
struct node* temp = node_ptr -> next;
node_ptr -> next = prev_ptr;
prev_ptr = node_ptr;
node_ptr = temp;
}
* ptr = prev_ptr;
}
}
扩展等价的递归定义:
void reverse(struct node** ptr) {
struct node* node_ptr;
if (node_ptr = * ptr) {
node_ptr -> next = NULL;
* ptr = reverse_rec(node_ptr, node_ptr -> next);
}
}
struct node* reverse_rec(struct node* prev_ptr, struct node* node_ptr) {
if (! node_ptr) { return prev_ptr; }
struct node* temp = reverse_rec(node_ptr, node_ptr -> next);
node_ptr -> next = prev_ptr;
return temp;
}
答案 2 :(得分:0)
这样可行,但使用递归来反转列表需要O(n)堆栈空间开销。这里的概念是推进L-> head的静态实例,同时为每个递归级别保留head的本地副本。递归一直持续到列表结束,然后使用head的本地实例反转列表,因为reverse()返回备份调用链。
void reverse(LL_t *L)
{
node_t *head;
if(L->head == NULL || L->head->next == NULL)
return;
head = L->head;
L->head = head->next;
reverse(L);
head->next->next = head; // reverse the nodes
head->next = NULL;
L->tail = head; // ends up setting tail to what was 1st node
}
答案 3 :(得分:0)
//反转链接列表的简单程序
void reverse(struct node * head_ref) { struct node * first;
struct node* rest;
if (head_ref == NULL)
return;
first = head_ref;
rest = first->next;
if (rest == NULL)
return;
reverse(rest);
first->next->next = first;
first->next = NULL;
head_ref = rest;
}