反转链表

题目:输入一个链表的头结点,反转该链表,并返回反转后链表的头结点。链表结点定义如下:

struct ListNode
{
      int       m_nKey;
      ListNode* m_pNext;
};

分析:这是一道广为流传的微软面试题。由于这道题能够很好的反应出程序员思维是否严密,在微软之后已经有很多公司在面试时采用了这道题。

为了正确地反转一个链表,需要调整指针的指向。与指针操作相关代码总是容易出错的,因此最好在动手写程序之前作全面的分析。在面试的时候不急于动手而是一开始做仔细的分析和设计,将会给面试官留下很好的印象,因为在实际的软件开发中,设计的时间总是比写代码的时间长。与其很快地写出一段漏洞百出的代码,远不如用较多的时间写出一段健壮的代码。

为了将调整指针这个复杂的过程分析清楚,我们可以借助图形来直观地分析。假设下图中lmn是三个相邻的结点:

a?b?…?l mànà…

假设经过若干操作,我们已经把结点l之前的指针调整完毕,这些结点的m_pNext指针都指向前面一个结点。现在我们遍历到结点m。当然,我们需要把调整结点的m_pNext指针让它指向结点l。但注意一旦调整了指针的指向,链表就断开了,如下图所示:

a?b?…l?m nà…

因为已经没有指针指向结点n,我们没有办法再遍历到结点n了。因此为了避免链表断开,我们需要在调整m的m_pNext之前要把n保存下来。

接下来我们试着找到反转后链表的头结点。不难分析出反转后链表的头结点是原始链表的尾位结点。什么结点是尾结点?就是m_pNext为空指针的结点。

public class Test_19 {

	public static void main(String[] args) {
		int[] arr = {1,2,3,4,5,6,7,8,9};
		signalList list = new signalList();
		for(int i =0;i<arr.length;i++){
			list.add(arr[i]);
		}
		list.printlist(list.getHead());
		list.printlist(reverseList(list.getHead()));
		
	}
	public static ListNode reverseList(ListNode head){
		if(head == null){
			return null;
		}
		ListNode reverseHead = null;//链表反转后的新头结点
		ListNode pnode = head;
		ListNode ppre = null;
		while(pnode != null){
			ListNode pnext = pnode.getNext();
			if(pnext == null){
				reverseHead = pnode;
			}
			pnode.setNext(ppre);
			ppre = pnode;
			pnode = pnext;
		}
		return reverseHead;
	}


}
class ListNode{
	private int key;
	private ListNode next;
	public int getKey() {
		return key;
	}
	public void setKey(int key) {
		this.key = key;
	}
	public ListNode getNext() {
		return next;
	}
	public void setNext(ListNode next) {
		this.next = next;
	}
	public ListNode(int key,ListNode next){
		this.key = key;
		this.next = next;
	}
}
class signalList{
	private ListNode head;
	public ListNode getHead() {
		return head;
	}
	public void setHead(ListNode head) {
		this.head = head;
	}
	private ListNode tail;
	public ListNode getTail() {
		return tail;
	}
	public void setTail(ListNode tail) {
		this.tail = tail;
	}
	private int size;
	public void add(int i){
		ListNode newnode = new ListNode(i,null);
		if(head == null){
			head = newnode;
			tail = newnode;
			size++;
			
		}
		else{
		tail.setNext(newnode);
		tail = newnode;
		size ++;
		}
	}
	public void printlist(ListNode head){
		if(head ==null){
			return;
			}
		ListNode pnode = head;
		while(pnode !=null){
			System.out.println(pnode.getKey());
		    pnode = pnode.getNext();
		}
	}
	
}


 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值