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

题目描述:

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;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值