链表

1.构造链表
2.逆序打印链表
     实现方法:
          a.用stack实现
          b.用递归实现
     测试用例:
          没有节点,只有一个节点,有多个节点
3.在O(1)时间删除节点
     实现方法:
          复制被删除节点的下一个节点,然后删除next节点
     测试用例:
          null,单个节点,多个节点
4.返回链表中倒数第k个节点
     实现方法:
          用两个指针,间距为k找到第k个节点.
     测试用例:
          空链表,链表长度小于k,链表长度等于k,链表长度大于k
5.链表反转
     实现方法:
          三个指针,指向前一个节点,中间节点,后一个节点
     测试用例:
          空链表,单个元素链表,两个元素链表,多个元素链表
6.合并两个已经排序的链表
     实现方法:
          设置三个指针,第一个指向已合并的链表的尾部,剩下两个分别指向链表的头
     测试用例:
          两个空链表,一个空链表,没有空链表
7.两个链表的第一个公共节点
     实现方法:
          遍历两个链表长度,求出链表长度之差,将问题转化为4:寻找链表的第k个节点
     测试用例:
          两个空链表,一个空链表,没有公共节点,公共节点为头节点,
          公共节点为尾节点,公共节点为中间节点
//list.h
#ifndef __LIST__
#define __LIST__

struct link_node{
	int m_val;
	link_node *next;

	link_node(int val,link_node* p){
		m_val =val;
		next = p;
	}
};

class link_list {
public:
	link_list();
	~link_list();

	/**  将节点插入到链表头 **/
	void head_insert_node(link_node *p);

	/**  将节点插入到链表尾**/
	void tail_inster_node(link_node *p);

	/**  插入链表节点 **/
	void normal_insert_node(link_node* p,link_node *insert_node);

	/**  逆序打印链表**/
	void print_list_reserve();

	/**   删除链表尾节点**/
	void head_delete_node();

	/**   删除链表头结点**/
	void tail_delete_node();

	/**  删除链表中p节点**/
	void normal_delete_node(link_node* p);

	/**   获取第链表第k个节点**/
	link_node* get_kth_node(int k);

	/**   创建链表节点**/
	link_node* create_link_node(int val);

	/**  反转链表 **/
	void reserve_list();

	/**  合并两个已排好序(非递增)的链表 **/
	void merge_list(link_list *head);

	/** 打印链表节点**/
	void print_list();

private:
	link_node *phead;

private:
	/** 逆序打印链表--内部递归函数 **/
	void print_list_reserve(link_node *);
};
#endif
//list.cpp
#include <iostream>
#include "list.h"

/** 函数名:    link_list
   *    功能描述:   构造函数
   *    参数列表:   无
   *    返回值  :   
   */ 
link_list::link_list ()
	:phead(NULL)
{
	std::cout<<"构造函数"<<std::endl;
}

/** 函数名:    ~link_list
   *    功能描述:   析构函数
   *    参数列表:   无
   *    返回值  :   
   */ 
link_list::~link_list()
{
	std::cout<<"析构函数"<<std::endl;
	while ( phead  ){
		head_delete_node();
	}
}

/** 函数名:    ~head_insert_node
   *    功能描述:   将节点插入到链表头
   *    参数列表:   待插入节点
   *    返回值  :   
   */ 
void link_list::head_insert_node(link_node *p)
{
	std::cout<<"将节点插入到链表头"<<std::endl;
	if ( p ){
		p->next = phead;
		phead   = p;
	}
}

/** 函数名:    tail_inster_node
   *    功能描述:   将节点插入到链表尾
   *    参数列表:   待插入节点
   *    返回值  :   
   */ 
void link_list::tail_inster_node(link_node *p)
{
	std::cout<<"将节点插入到链表尾"<<std::endl;
	if ( p ){
		if ( phead ){
			link_node *ptail = phead;
			while ( ptail->next ){
				ptail = ptail->next;
			}
			ptail->next = p;
			p->next = NULL;
		} else {
		    phead = p;
			p->next = NULL;
		}
	}
}

/**  插入链表节点 **/
/** 函数名:    normal_insert_node
   *    功能描述:   插入链表节点
   *    参数列表:   查找链表中节点p,在节点p后面插入节点insert_node
					 若链表中存在p,则插入其后,否则do nothing
   *    返回值  :   无
   */ 

void link_list::normal_insert_node(link_node* p,link_node *insert_node)
{
	std::cout<<"插入链表节点"<<std::endl;
	if ( phead && insert_node && p ){
		link_node *curr_node = phead;
		while ( curr_node && curr_node!=p){
			curr_node = curr_node->next;
		}
		if ( curr_node ){
			insert_node->next  = curr_node->next;
			curr_node->next    = insert_node;
		}
	}
}

/**  逆序打印链表**/
/** 函数名:    print_list_reserve
   *    功能描述:   逆序打印链表
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::print_list_reserve()
{
	std::cout<<"逆序打印链表"<<std::endl;
	if ( phead ){
		link_node *p = phead;
		print_list_reserve(p);
		std::cout<<std::endl;
	} else {
	    std::cout<<"链表为空."<<std::endl;
	}
	
}

/**  逆序打印链表**/
/** 函数名:    print_list_reserve
   *    功能描述:   逆序打印链表--内部递归函数
   *    参数列表:   当前链表节点
   *    返回值  :   
   */ 
void link_list::print_list_reserve(link_node *p)
{
	if ( p->next ){
		print_list_reserve(p->next);
	}
	std::cout<<p->m_val<<" ";
}

/**   打印链表**/
/** 函数名:    head_delete_node
   *    功能描述:   打印链表
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::print_list()
{
	std::cout<<"正序打印链表节点"<<std::endl;
	link_node* p =phead;
	while ( p ){
		std::cout<<p->m_val<<" ";
		p = p->next;
	}
	std::cout<<std::endl;
}
/**   删除链表头节点**/
/** 函数名:    head_delete_node
   *    功能描述:   删除链表头节点
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::head_delete_node()
{
	std::cout<<"删除链表头节点"<<std::endl;
	if ( phead ){
		link_node *p =phead->next;
		delete phead;
		phead = p;
	}
}

/**   删除链表尾结点**/
/** 函数名:    tail_delete_node
   *    功能描述:   删除链表尾结点
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::tail_delete_node()
{
	std::cout<<"删除链表尾结点"<<std::endl;
	if ( phead ){
		if ( phead->next ){
			link_node *p = phead;
			while ( p->next->next ){
				p = p->next;
			}
			delete p->next;
			p->next = NULL;
		} else {
			delete phead;
			phead = NULL;
		}
	}
}

/**  删除链表中p节点**/
/** 函数名:    normal_delete_node
   *    功能描述:   删除链表中p节点
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::normal_delete_node(link_node* p)
{
	std::cout<<"删除链表中p节点"<<std::endl;

	if ( phead && p ){
		link_node* curr = phead;
		if ( phead == p ){
			curr = curr->next;
			delete phead;
			phead = curr;
		}else if ( p->next ){
			curr = p->next;
			p->m_val = p->next->m_val;
			p->next = p->next->next;
			delete curr;
		} else {
			while ( curr->next && curr->next!=p ){
				curr = curr->next;
			}
			if ( curr->next == p ){
				curr->next = curr->next->next;
				delete p;
			}
		}
	}
}

/** 函数名:    get_kth_node
   *    功能描述:   获取第链表第k个节点
   *    参数列表:   第k个节点
   *    返回值  :   
   */ 
link_node* link_list::get_kth_node(int k)
{
	std::cout<<"获取第链表第k个节点"<<std::endl;
	link_node *p1 = phead;
	link_node *p2 = phead;
	int i = 0;
	while ( p1 && i<k  ){
		p1 = p1->next;
		i++;
	}
	while ( p1 ){
		p1 = p1->next;
		p2 = p2->next;
	}
	return i == k ? p2:NULL;
}

/**   创建链表节点**/
/** 函数名:    create_link_node
   *    功能描述:   创建链表节点
   *    参数列表:   节点的值
   *    返回值  :   
   */ 
link_node* link_list::create_link_node(int val)
{
	std::cout<<"创建链表节点"<<std::endl;
	link_node * p = new link_node(val,NULL);
	return p;
}

/**  反转链表 **/
/** 函数名:    reserve_list
   *    功能描述:   反转链表
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::reserve_list()
{
	std::cout<<"反转链表"<<std::endl;
	link_node *pre = NULL;
	link_node *curr = phead;
	link_node *last = NULL;

	while ( curr ){
		last          = curr->next;
		curr->next    = pre ;
		pre           = curr;
		curr          = last ;
	}
	phead = pre ;
}

/**  合并两个已排好序的链表 **/
/** 函数名:    merge_list
   *    功能描述:   合并两个已排好序的链表
   *    参数列表:   无
   *    返回值  :   
   */ 
void link_list::merge_list(link_list *list)
{
	std::cout<<"合并两个已排好序的链表"<<std::endl;
	if ( list ){
		link_node *phead1   = phead;
		link_node *phead2  = list->phead;
		link_node *tail_node    = NULL; 
		if ( phead1 == NULL ){
			phead = phead2;
		} 
		if ( phead1 && phead2 ){
			if (  phead1->m_val > phead2->m_val ){
				phead = phead1;
				phead1 = phead1->next;
			} else {
				phead = phead2;
				phead2 = phead2->next;
			}
			tail_node = phead;	
		}

		while ( phead1 && phead2 ){
			if (  phead1->m_val > phead2->m_val ){
				tail_node->next = phead1;
				phead1 = phead1->next;
			} else {
			    tail_node->next = phead2;
				phead2 = phead2->next;
			}
			tail_node = tail_node->next;	
		}
		if ( tail_node ){
			tail_node->next = phead1->next == NULL 
				? phead2 : phead1;
		}
		list->phead = NULL;
	}
	
}

//main
#include <iostream>
#include "list.h"

using namespace std;


int main()
{
	
	link_list myList ;

	//测试空链表的删除
	myList.get_kth_node(7);

	//测试空链表反转
	myList.reserve_list();

	myList.head_insert_node(myList.create_link_node(1));
	myList.print_list();


	myList.get_kth_node(7);

	//测试链表反转
	myList.reserve_list();
	myList.print_list();

	link_list listTemp ;
	for ( int i=0 ; i<10; i++ ){
		myList.head_insert_node(myList.create_link_node(i));
	}
	//myList.reserve_list();
	myList.tail_delete_node();
	myList.print_list();
	
	for ( int i=0 ; i<10; i++ ){
		listTemp.tail_inster_node(listTemp.create_link_node(i));
	}
	listTemp.reserve_list();
	listTemp.print_list();
	listTemp.merge_list(&myList);

	listTemp.print_list();
	return 0;
}





          
           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值