单链表的反转(数据结构 面试题)

来源:互联网 发布:淘宝美工每天工作任务 编辑:程序博客网 时间:2024/04/19 01:13
编写一个算法来颠倒一个链表,该链表的第一个结点由first指向。不要复制列表元素;而是重置链接和指针,使得first指向原来的最后一个结点,并且结点之间的所有链接都反向。

思路:因为题目中明确说明不能复制元素,所以通过复制来重置另外一个链表的想法被终止。我们想到,如果要改变连接的指向,又能够要使链表继续遍历,那么最少需要先遍历到几个结点呢?答案是3个。如图:(第二张是将要结束时的情况)

3个结点之后就可以对第一个连接进行反转,直到cur->next-==NULL结束,然后对最后一个特殊处理即可,详见代码。

#include <iostream>#include <ctime>#include <string>#include <string.h>#include <algorithm>using namespace std;template <typename T>class clist{public:struct node{T value;node* next;node(T v=NULL) :value(v){}};node *front;node *tail;int size;clist(node *f = NULL, node*t = NULL, int s = NULL) :front(f), tail(t), size(s){}~clist(){if (!size){node* temp = front;node* pre = NULL;while (temp != tail){pre = temp;temp = temp->next;delete pre;}delete temp;size = 0;}}void build_list_rand(int len){//创建一条任意长度的为len的链表srand((unsigned)time(NULL));front = new node();front->value = rand()%100+1;node* temp = front;size++;while (size<len){temp->next = new node;temp->value = rand()%100+1;temp = temp->next;size++;}tail = temp;tail->value = rand()%100+1;tail->next = NULL;}void swap(node* &a, node* &b){//交换两个指针node* temp = a;a = b;b = temp;}void clist<T>::reserve(){//反转函数node* head=NULL, *mid=NULL, *follow=NULL, *temp=NULL;if (size <= 1)return;else if (size == 2){swap(front, tail);front->next = tail;tail->next = NULL;}else{swap(front, tail);head = tail;mid = tail->next;follow = mid->next;while (follow != NULL){mid->next = head;head = mid;mid = follow;follow = follow->next;}mid->next = head;tail->next = NULL;}}void display(){//打印整个链表和长度node* temp = front;while (temp != tail){cout << temp->value << ' ';temp = temp->next;}cout << temp->value << endl;cout << "the size is " << size << endl;}};int main(){clist<int> a;int b;cout << "请输入您要反转的链表的长度:" << endl;cin >> b;a.build_list_rand(b);a.display();a.reserve();a.display();return 0;}
运行结果:


1 0
原创粉丝点击