1. 单链表的倒置输出

// ListNode
typedef struct LNode {
    int key;
    struct LNode *next;
}LNode;


分析:这是一道很有意思的面试题,此题以及此题的变体经常出现在各大公司的面试、笔试中。


看到这道题后,第一反应是从头到尾输出比较简单。然后经过分析,这道题有以下几种解决方法:

  1. 将链表中节点的指针反转过来,然后在从头到尾输出节点中的值

  2. 当要倒置输出值时,我们会想到用栈来实现。所以这种方法是,遍历链表节点中的值,依次入栈,最后弹栈输出

仔细分析这两种方法,解决问题都需要两步。方法一显然不是面试官想要的算法,而方法二需要维护一个额外的栈,在不借用STL容器时,实现起来比较麻烦,那么有没有一步到位的算法呢?

答案是肯定的,仔细分析第二种方法,需要用到栈来实现这个函数,而递归本质上就是一个栈结构。于是想到要用递归的思想来解决问题。下面贴出用递归实现的代码,这类问题要理解,并且能够运用这种递归思想来解决类似的问题:

// given a head pointer, print key from the end to the beginning
void printListReversely(LNode *head) {
    if (head) {
        if (head->next)
            printListReversely(head->next);        
    }
    printf("%d ", head->key);
}


扩展:

  1. 给定一个未知长度的字符串,从尾到头输出一个字符窜(在不使用string.h文件中strlen函数的前提下)

  2. 定义一个函数求字符串的长度,要求函数内部不能声明任何变量

// print string reversely
void printStringReversely(const char *str) {
    if (*str != '\0') {
        if (*(str + 1) != '\0')
            printStringReversely(str + 1);
    } else {
        printf("\n");
        return;
    }
    printf("%c", *str);
}


// strlen implemented by recursion
int strlen(const char *str) {
    if (*str == '\0')
        return 0;
    else
        return strlen(str + 1) + 1;
}




### 回答1: 可以利用三个指针prev、p、next,其中prev用来记录当前结点的前驱结点,p用来记录当前结点,next用来记录当前结点的后继结点。具体实现步骤如下: 1.先将第一个结点的next域置为NULL。 2.从第二个结点开始,依次将每个结点的next域指向其前驱结点。 3.依次往后移动指针prev、p、next,直到next为NULL。 4.将链表的头结点指向原链表的尾结点。 5.输出倒置后的单链表的各元素值。 以下是代码实现: ### 回答2: 要将单链表倒置,可以通过遍历链表并修改指针的方式来实现。具体步骤如下: 1. 输入n的值,表示单链表的元素个数。 2. 输入n个整数值,作为单链表的各元素值,创建单链表。 3. 定义三个指针prev、curr和next,分别指向当前节点、前一个节点和下一个节点。 4. 初始化prev为NULL,curr为链表的头节点。 5. 遍历链表,直到curr为NULL: - 将next指针指向curr的下一个节点。 - 将curr的next指针指向prev,将prev指针指向curr。 - 将curr指针指向next。 6. 遍历完整个链表后,prev指针即指向倒置后的链表的头节点。 7. 遍历倒置后的链表输出各元素值,用空格分隔。 以下为具体的代码实现: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reverseLinkedList(head): prev = None curr = head while curr: next = curr.next curr.next = prev prev = curr curr = next return prev n = int(input()) values = list(map(int, input().split())) # 创建单链表 head = ListNode(values[0]) node = head for i in range(1, n): newNode = ListNode(values[i]) node.next = newNode node = newNode # 倒置单链表 reversedHead = reverseLinkedList(head) # 输出倒置后的单链表的各元素值 result = [] node = reversedHead while node: result.append(str(node.val)) node = node.next print(" ".join(result)) ``` 这样就可以将单链表倒置,并输出倒置后的单链表的各元素值,各元素值之间用空格分隔。 ### 回答3: 将单链表倒置,可以利用三个指针进行操作。 首先创建三个指针pre、cur和next,分别指向当前节点的前一个节点、当前节点和当前节点的下一个节点。 1. 将pre指向null,cur指向第一个节点。 2. 对每一个节点,利用next指针保存当前节点的下一个节点,然后将当前节点的next指向pre,即将当前节点指向前一个节点。 3. 将pre指向当前节点,cur指向next指针保存的下一个节点。 4. 重复步骤2和3,直到cur指向null。 5. 最后将链表的头指针指向pre,即可得到倒置后的链表。 下面以一个例子来说明过程: 输入:3 1 2 3 链表原始状态:1 -> 2 -> 3 -> null 初始化pre为null,cur为第一个节点1。 保存next为cur的下一个节点2,即1 -> 2。 将cur的next指向pre,即将1 -> null。 将pre指向cur,即pre指向1。 将cur指向next,即将cur指向2。 链表状态:null <- 1 2 -> 3 -> null 重复上面的步骤,直到cur指向null: 保存next为cur的下一个节点3,即2 -> 3。 将cur的next指向pre,即将2 -> 1。 将pre指向cur,即pre指向2。 将cur指向next,即将cur指向3。 链表状态:null <- 2 <- 1 3 -> null 重复上面的步骤: 保存next为null。 将cur的next指向pre,即将3 -> 2。 将pre指向cur,即pre指向3。 将cur指向next,即将cur指向null。 链表状态:null <- 3 <- 2 <- 1 null 最后将链表的头指针指向pre,即可得到倒置后的链表输出: 3 2 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值