`
cq520
  • 浏览: 164729 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

玩转单链表

阅读更多

       学会了单链表的基本操作之后,我们就可以自定义一些非常有意思的功能了,例如对单链表中的元素进行排序,(排序规则可以由自己定),将链表翻转等等,这里主要是讲老师布置的几个问题,我觉得也非常有趣,大家也可以思考一下,由于这些方法几天前就写完了,五一假在家中也没有对之前的链表进行更多的修改了,所以还是用之前所写过的单链表结构继续添加功能吧。

       在实现所有功能之前先来个前言,接下来的这两个方法对后面的每一步都是至关重要的,第一个是获取链表长度的方法:

获取链表长度的方法其实可以是打印链表方法的翻版,我最开始的时候也是这样做的,不过后来发现了一个更好的更不容易出错的方法,在链表类中定义一个size属性

      int size=0;

    然后在所有的对链表有长度修改的方法中都对size进行一次修改,例如添加元素的方法最后加一句size++,删除元素的方法最后加一句size--等等(当然size不能小于0)。

    这样获取size的方法中只需要一句话就可以解决了:

int size(){

           return size;

  }

另外一个就是获取指定位置结点元素的方法,如下:

/**
* 查找指定位置结点元素的方法
  */
public Node get(int index){
	Node node=head;
	int j=1;
	//找到第index
	while(node!=null&&j<index){
		node=node.next;
		j++;
	}
	return node;
}

 

下面在具体问题中来看一下这两个方法的应用吧。

                 1.对链表中的元素进行排序(如果链表中的元素是整数的话)

相信看完前两个方法之后,排序的方法已然在心中出现了,如果这不是一个单链表而是一个数组的话,对数组进行排序相信大家都不会陌生了,所以这里也只是用到了最简单的冒泡排序思想而已:

 

/**
 * 如果链表中的元素是整型元素,则排列链表
*/
public void sort(){
	Object obj=null;
	Node temp=new Node(obj);//媒介结点
	for(int i=0;i<=size();i++){
		for(int j=i+1;j<=size();j++){
			//冒泡排序思想,交换数据域
			if(Integer.parseInt((String)get(i).obj)>Integer.parseInt((String)get(j).obj)){
				temp.obj=get(i).obj;
				get(i).obj=get(j).obj;
				get(j).obj=temp.obj;
			}
		}
	}
}

2将链表中的元素封装到一个数组当中

看到这里大家可能会觉得奇怪,为什么这个方法不写在上面,第一个方法不就是利用了这个思想么?其实只是因为我是在做完第一个题目之后才想到的这个方法,所以放在之后讲,我想这正跟我们的学习过程一样,很多简单的方法是在做了复杂的方法之后才想出来的:

 

/**
 * 将链表封装成一个对象数组
*/
public Object[] toArray(){
	//创建
	Object obj[]=new Object[size()];
	Node node=head;
	int j=0;
	while(node!=null&&j<obj.length){
		obj[j++]=node.obj;
		node=node.next;
	}
	return obj;
}

 

3. 将链表翻转

最开始看到这个题目的时候,我还在反复推敲,如何把链表的引用域与数据域对调过来,因为这样就可以实现链表的翻转的工作,在那折腾了半个小时之后才发现,是我2B了,要实现链表翻转其实就像链表排序一样,只要交换数据域就行了,方法如下:

 

/**
 * 翻转链表的方法
 */
public void turn(){
	int j=size(); //获取最后一个下标位置
	//将前一半与后一半的位置交换
	Object temp;
	for(int i=1;i<=size()/2;i++){
		temp=get(i).obj;
		get(i).obj=get(j).obj;
		get(j).obj=temp;
		j--;
	}
}

       4如果该单链表具有环,怎么样找到环的入口位置?

这里采用的是穷尽搜索的方法,当然你还可以用效率更高的二分搜索法,不过我想不管是哪个方法,在搜索之前先判断要不要搜索都比搜索本身来的快一点,如何判断一个链表是否有环呢?很简单,当last结点的next域为空时链表不就没有环了么,方法如下:

      

/**
 * 搜索环链表环的位置的入口
*/
public void searchHoop(){
	Node node=head;
	int location=1; //环的入口位置
	while(node!=null&&location<=size()){
		node=node.next;//寻找下一个结点
		if(last.next==null){
			System.out.println("该链表没有环");
			break;
		}
		//如果最后一个结点的引用指向了之中的某一个结点
		else if(last.next==node&&location<=size()){
			System.out.println("环的入口位置为第"+location+"个结点");
			break;
		}
		location++;
	}
}

方法实现方面就先讲到这了,不过由于之前的发的那篇关于单向链表的实现上,语法结构其实并不严谨,后面几个方法在使用起来可能需要稍做揣摩,此外,也希望大家一起来探讨一下更多有趣的方法。

0
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics