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

【c++版数据结构】单链表复习之常见面试题型1

2016-03-10 15:47 567 查看
题目描述:

1:从尾到头依次打印单链表

2:在链表中删除指定的节点

3:假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个节点(不是第一个,也不是最后一个节点),请将该节点从单链表中删除。

4:假设有一个没有头指针的单链表,一个指针指向此单链表中一个节点,要求在此节点前插入一个节点
5:编写一个函数,给定一个链表的头指针,要求只遍历一次,将单链表中的元素顺序反转过来

解题思路及其代码如下:(单链表采用模板类,无头节点)

List.h

#ifndef _LIST_H_
#define _LIST_H_

#include<iostream>
#include<cstdlib>
#include<cassert>
#include<stack>
using namespace std;

template<typename T>
class List;

template<typename T>
class ListNode
{
friend class List<T>;
public:
ListNode(const T val = 0, ListNode<T> *next = NULL) :_val(val), _next(NULL){}
private:
T _val;
ListNode<T> *_next;
};

template<typename T>
class List
{
public:
List(){
this->head = NULL;
}
bool push_back(const T&val){
ListNode<T> *new_node = buy_node(val, NULL);
if (NULL == new_node){
return false;
}
if (head == NULL){
head = new_node;
}
else{
ListNode<T> *tmp = head;
while (NULL != tmp->_next){
tmp = tmp->_next;
}
tmp->_next = new_node;
}
return true;
}
bool push_front(const T&val){
ListNode<T> *new_node = buy_node(val, NULL);
if (NULL == new_node){
return false;
}
else{
new_node->_next = head;
head = new_node;
}
return true;
}
bool pop_back(){
if (is_empty()){
cout << "the list is already empty,can not be pop!" << endl;
return false;
}
if (head->_next == NULL){
delete head;
head = NULL;
}
else{
ListNode<T> *tmp = head;
while (tmp->_next->_next != NULL){
tmp = tmp->_next;
}
delete tmp->_next;
tmp->_next = NULL;
}
return true;
}
bool pop_front(){
if (is_empty()){
cout << "the list is already empty,can not be pop!" << endl;
return false;
}
else{
ListNode<T> *tmp = head;
head = head->_next;
delete tmp;
return true;
}
}
~List(){
while (head != NULL){
pop_back();
}
}
void print()const{
ListNode<T> *tmp = head;
while (NULL != tmp){
cout << tmp->_val << "->";
tmp = tmp->_next;
}
cout <<"NULL"<< endl;
}

//<<从尾到头依次打印单链表>>
//1:栈 2:递归
//如果链表元素很多,递归的方式会导致栈溢出,所以第一种方式鲁棒性更好
void print_from_tail_by_stack()const{
stack<ListNode<T> *> st;
ListNode<T> *tmp = head;
while (tmp != NULL){
st.push(tmp);
tmp = tmp->_next;
}
while (!st.empty()){
tmp = st.top(); //注意,stack的pop函数只是将栈顶元素删除
st.pop(); //(无法获取栈顶元素)->若要获取必须要通过top函数
cout << tmp->_val << "->";
}
cout << "NULL" << endl;
}
void print_form_tail_by_recursion(){
_print_form_tail_by_recursion(head);
cout <<"NULL"<< endl;
}

//在链表中删除指定的节点
bool delete_node(const T &val){
if (head->_val == val){
ListNode<T> *tmp = head;
head = head->_next;
delete tmp;
}
else{
ListNode<T> *prev = head;
while (prev->_next != NULL && prev->_next->_val != val){
prev = prev->_next;
}
if (prev->_next == NULL){
cout << "it is not exist!" << endl;
return false;
}
else{
ListNode<T> *tmp = prev->_next;
prev->_next = tmp->_next;
delete tmp;
}
}
return true;
}

//问题描述:假设有一个没有头指针的单链表。一个指针指向此单链表中间的
//一个节点(不是第一个,也不是最后一个节点),请将该节点从单链表中删除。
//解题思路:将该节点的后面一个节点的内容,拷贝到该节点,然后将后一个节点删除

void delete_mid_node(ListNode<T> *cur){
ListNode<T> *next = cur->_next;
cur->_val = next->_val;
cur->_next = next->_next;
delete next;
}

//编写一个函数,给定一个链表的头指针,要求只遍历一次,将单链表中的元素顺序反转过来。
//指向第二个节点,然后将第二个节点以及之后的节点头插
void reverse1(){
if (head == NULL || head->_next == NULL){//链表为空或者只有一个节点,无需逆置
return;
}
ListNode<T> *tmp = head->_next;
head->_next = NULL;
while (tmp != NULL){
ListNode<T> *new_head = tmp;
tmp = tmp->_next;
new_head->_next = head;
head = new_head;
}
}
void reverse2(){//三个指针
if (head == NULL || head->_next == NULL){//链表为空或者只有一个节点,无需逆置
return;
}

ListNode<T> *prev = head;
ListNode<T> *cur = prev->_next;
ListNode<T> *next = NULL;

head->_next = NULL;
while (cur != NULL){
next = cur->_next;
cur->_next = prev;
head = cur;
prev = cur;
cur = next;
}
}

//问题描述:假设有一个没有头指针的单链表,一个指针指向此单链表中一个节点,要求在
//此节点前插入一个节点
//思路:在该节点之后插入该节点,然后交换二者的数据
void insert(ListNode<T> *cur,int val){
assert(cur != NULL);
ListNode<T> *new_node = buy_node(val, NULL);
assert(new_node != NULL);
new_node->_next = cur->_next;
cur->_next = new_node;
swap(cur->_val, new_node->_val);
}
private:
ListNode<T> *buy_node(const T val = 0, ListNode<T> *next = NULL){
ListNode<T> *tmp = new ListNode<T>(val,next);
return tmp;
}
bool is_empty()const{
return head == NULL;
}
void _print_form_tail_by_recursion(ListNode<T> *head){//递归方式
if (head == NULL){
return;
}
else{
_print_form_tail_by_recursion(head->_next);
cout << head->_val << "->";
}
}
ListNode<T> *head;
};
#endif


main.cpp
#include"List.h"

void test1()
{
List<int> list;
for (int i = 0; i < 10; ++i){
list.push_front(i);
}
list.print();
//list.print_form_tail_by_recursion();
//list.print_from_tail_by_stack();

//for (int i = 0; i < 5; ++i){
//	list.pop_back();
//	list.pop_front();
//}
//list.print();
}
//
void test2()
{
List<int> list;
for (int i = 0; i < 10; ++i){
list.push_front(i);
}
list.print();
list.delete_node(0);
list.print();
list.delete_node(3);
list.print();
list.delete_node(9);
list.print();
}
//reverse
void test3()
{
List<int> list;
for (int i = 0; i < 10; ++i){
list.push_front(i);
}
list.print();
list.reverse2();
//list.reverse1();
list.print();
}
int main()
{
test3();
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息