您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法(3 Reverse链表)

2015-07-20 13:27 295 查看
首先个人理解数组和链表的异同点:

1:数组是一个有固定容量的容器,在内存中是一个一个排列着,有自己的固定长度,虽然可以生成动态数组,但是不建议,因为消耗内存。所以如果想从数组中插入或者删除一个元素的时候,就显得资源消耗比较大,因为每插入一个,数组就要向后移动插入位置之后的每一个位置。所以数组在插入删除中效率是比较低的,然后数组可以通过index索引,直接查到数组的对应索引的元素。

2:链表跟数组是相反的,链表可以动态插入一个元素,通过指针指向的不同去实现插入删除,所以显得非常方便,因为不需要消耗大量的资源去增删元素,但是,链表由于只有头,(在这里我们只考虑头head)和一个指针指向,所以比如我想找到某一个元素的时候,利用链表的效率是非常慢的,一个一个从头开始,肯定比直接拿索引慢。

Boom…….反转链表

之前上一篇写过翻转数组,于是,必须要有反转链表,反转链表之前,说说斐波那契数列

斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列、费波那西数列、费波拿契数、费氏数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字来说,就是斐波那契数列列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两数相加。


这个例子主要是用来理解递归的

//主要代码
public void fib(int n){
if(n<2){
return n;
}
else{
rerurn fib(n-1)+fib(n-2);
}
}


从这个例子可以看到,由于每一次都是进行相同的操作,所以可以使用递归,也就是调用本身

但是,这个算法的执行效率非常低,因为已经是平方阶,后续可以使用标记进行优化。

说回反转链表

非递归反转代码如下:

public node* reverse(node* head){
if(head->next==nullptr||head==nullptr){
return head;//如果没有其他结点,直接返回头结点,无需翻转
}else{
node* p=head->next;//保存第二个界面
node* p_pre=head;//保存头结点
head->next=nullptr;//断开头结点
if(p!=nullptr){
node* p_next=p->next;
p->next=p_pre;
p_pre=p;
p=p_next;
}
return p_pre;
}
}


递归反转链表

public node* reverse(node* head){
if(head->next==nullptr||head==nullptr){
return head;//如果没有其他结点,直接返回头结点,无需翻转
}else{
node* second=head->next;
node* new_head=reverse(second);
second_next=head;
head->next=null;
return new_head;
}
}


以上代码,如有错误,不吝赐教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: