精华内容
下载资源
问答
  • 链表C++实现

    2013-12-29 00:39:06
    链表C++实现  1 #include assert.h>  2   3 templatetypename T>  4 class CNode   5 {  6 public:  7 T data;  8 CNodeT> *next;  9 CNode():data(T()),next(NULL)   10 ...
    展开全文
  • 链表c++实现

    2014-02-22 15:35:00
    else //没有找到节点,pn指向最后一个节点,将新节点插入链表尾   {     cout没有找到,插入到链表尾。";     pn->setNext(p);    }   } void Linklist::deleteNum(int num) //删除节点 {...

    #include <iostream.h>
    //   #define NULL 0

    class Node //节点类
    {
    public:
     Node(){}
     Node(int n){ num=n; next=NULL; }
     Node(int n, Node *p){ num=n; next=p;}

     void setNum(int n) {num =n;}
     void setNext(Node *p){next =p;}
     
     int getNum(){return num;}
     Node *getNext(){ return next;}

    private:
     int num;
     Node *next;
    };

    class Linklist //链表类
    {
    public:
     Linklist(){head=NULL;}
     Linklist(int n){ head = new Node(n); }

     void addAtEnd(int n);
     void addAtEnd(Node *p);
     void visitAllNode();
     void addBeforeNum(Node *p, int num); //在节点值为num之前添加新节点p
     void deleteNum(int num);//删除值为num的节点
    private:
     Node *head;
    };

    void Linklist::addAtEnd(int n)  //往链表尾添加节点
    {
     Node *p=head;
     if(head==NULL){ head = new Node(n);}
     else
     {
      while(p->getNext()!=NULL)
      { p= p->getNext(); }//用p来指向最后一个节点
      p->setNext(new Node(n));//插入节点
     }
     
    }
    void Linklist::addAtEnd(Node *p) //往链表尾添加节点
    {
     Node *pn=head;
     if(head==NULL) { head=p; }
     else
     {
      while(pn->getNext()!=NULL)
      { pn=pn->getNext(); }//用pn来指向最后一个节点
      pn->setNext(p);//插入节点
     }
     
    }

    void Linklist::visitAllNode()//遍历链表
    {
     Node *p;
     p=head;

     if(p==NULL){cout<<"空链表!"<<endl;}
     else
     {
      cout<<"表头: ";
      while(p->getNext()!=NULL)
      {
       cout<<p->getNum()<<" --> ";
       p=p->getNext();
      }
      cout<<p->getNum()<<" 表尾"<<endl;
     }
    }

    void Linklist::addBeforeNum(Node *p, int num) //在节点值为num之前添加新节点p
    {
     Node *pn=head,*follow=pn;
     if(pn==NULL)
     {
      cout<<"空链表!插入节点。";
      head= p;
      return;
     }

     while(pn->getNext() != NULL && pn->getNum() != num)
     // 查找指向节点值为num的节点
     { 
      follow = pn; //follow一直指向pn前的一个节点
      pn = pn->getNext();
     }
     if(pn==head && pn->getNum() == num)//找到节点,且为头指针
     {
      p->setNext(pn);
      head=p;
     }
     else if(pn->getNum() ==  num) //找到此节点,注:follow指向其上一节点
     {
      p->setNext(pn);
      follow->setNext(p);
     }
     else //没有找到节点,pn指向最后一个节点,将新节点插入链表尾
     {
      cout<<"没有找到,插入到链表尾。"<<endl;
      pn->setNext(p); 
     }
     
    }

    void Linklist::deleteNum(int num) //删除节点
    {
     Node *p=head,*follow=p;
     if(p->getNum() == num)//若删除的节点为第1个节点
     {
      head = p->getNext();
      delete p;
     }
     else
     {
      while(p->getNext()!=NULL && p->getNum() != num)
      { 
       follow = p;//follow一直指向p的前一个节点
       p = p->getNext();
      }
      if(p->getNum() == num)
      {
       follow->setNext(p->getNext());
       delete p;
      }
      
     }
    }

    void main()
    {
     Linklist *pl=NULL;
     int num, n;
     Node *p;
     char option;
     while(1)
     {
      cout<<"\n链表操作练习:"<<endl;
      cout<<"1: 创建链表"<<endl;
      cout<<"2: 在链表尾插入新节点"<<endl;
      cout<<"3: 在节点值为num的节点前插入新节点"<<endl;
      cout<<"4: 删除节点"<<endl;
      cout<<"5: 遍历节点"<<endl;
      cout<<"0: 退出"<<endl;
      
      cout<<"\n请输入你的选择:";
      cin>>option;
      
      switch(option)
      {
      case '0':
       break;
      case '1':
       cout<<"请输入第一个节点值"<<endl;
       cin>>num;
       pl = new Linklist(num);
       pl->visitAllNode();
       break;
      case '2':
       cout<<"请输入节点值:";
       cin>>num;
       if(pl==NULL){ pl = new Linklist(num);}
       else
       {
        pl->addAtEnd(num); //pl->addAtEnd(new Node(num));
       }
       pl->visitAllNode();
       break;
      case '3':
       cout<<"请输入插入的节点值:";
       cin>>num;
       cout<<"请输入要插入到哪个节点前,以节点的值表示:";
       cin>>n;
       pl->addBeforeNum(new Node(num), n);
       pl->visitAllNode();
       break;
      case '4':
       cout<<"请输入要删除的节点的值:";
       cin>>num;
       pl->deleteNum(num);
       pl->visitAllNode();
       break;
      case '5':
       pl->visitAllNode();
       break;
      default:
       cout<<"你输入错误,请重新输入!"<<endl;
      }

      if(option == '0' )
       break;
     }

    }


    展开全文
  • 链表C++实现 精品文档 精品文档 收集于网络如有侵权请联系管理员删除 收集于网络如有侵权请联系管理员删除 精品文档 收集于网络如有侵权请联系管理员删除 #include<iostream> using namespace std; //节点类 class ...
  • 二叉树链表C++实现

    2018-08-09 13:05:00
    二叉树链表C++实现 结点的构造 源代码:https://github.com/cjy513203427/C_Program_Base/tree/master/57.%E4%BA%8C%E5%8F%89%E6%A0%91%E9%93%BE%E8%A1%A8%E5%AE%9E%E7%8E%B0 #pragma once #...

    二叉树链表C++实现

    结点的构造

    源代码:https://github.com/cjy513203427/C_Program_Base/tree/master/57.%E4%BA%8C%E5%8F%89%E6%A0%91%E9%93%BE%E8%A1%A8%E5%AE%9E%E7%8E%B0

    #pragma once
    #ifndef NODE_H
    #define NODE_H
    
    class Node
    {
    public:
        Node();
        Node *SearchNode(int nodeIndex);
        void DeleteNode();
        void PreorderTraversal();
        void InorderTraversal();
        void PostorderTraversal();
    
        int index;
        int data;
        Node *pLChild;
        Node *pRChild;
        Node *pParent;
    };
    
    #endif // !NODE_H

    需要实现的方法

    #pragma once
    #ifndef  TREE_H
    #define TREE_H
    #include"Node.h"
    class Tree
    {
    public:
        Tree();//创建树
        ~Tree();//销毁树
        Node *SearchNode(int nodeIndex);//搜索结点
        bool AddNode(int nodeIndex, int direction, Node* pNode);//添加结点
        bool DeleteNode(int nodeIndex, Node* pNode);//删除结点
        void PreorderTraversal();//前序遍历
        void InorderTraversal();//中序遍历
        void PostorderTraversal();//后序遍历
    private:
        Node * m_pRoot;
    };
    
    #endif // ! TREE_H

    创建树

    申请一段内存

    Tree::Tree()
    {
        m_pRoot = new Node();
    };

    创建结点

    Node::Node()
    {
        index = 0;
        data = 0;
        pLChild = NULL;
        pRChild = NULL;
        pParent = NULL;
    }

     

    销毁树

    调用Node的DeleteNode方法

    Tree::~Tree()
    {
        m_pRoot->DeleteNode();
    }

    如果当前Node对象(this)的pLChild不为空,递归调用DeleteNode方法,this->pLChild变成了新的this,直到delete this销毁掉

    如果当前Node对象(this)的pRChild不为空,递归调用DeleteNode方法,this->pRChild变成了新的this,直到delete this销毁掉

    如果当前Node对象(this)的pParent不为空,如果父节点的左子节点等于当前Node对象,将当前结点置空

    如果当前Node对象(this)的pParent不为空,如果父节点的右子节点等于当前Node对象,将当前结点置空

    思路:指定索引向下搜索从最底层子节点开始删除,再往上回到指定索引并删除,删除的顺序是后序

     

     

    void Node::DeleteNode()
    {
        if (this->pLChild != NULL)
        {
            this->pLChild->DeleteNode();
        }
        if (this->pRChild != NULL)
        {
            this->pRChild->DeleteNode();
        }
        if (this->pParent != NULL)
        {
            if (this->pParent->pLChild == this)
            {
                this->pParent->pLChild = NULL;
            }
            if (this->pParent->pRChild == this)
            {
                this->pParent->pRChild = NULL;
            }
        }
        
        delete this;
    }

    搜索结点

    传入索引,调用Node的SearchNode方法

    Node *Tree::SearchNode(int nodeIndex)
    {
        return m_pRoot->SearchNode(nodeIndex);
    }

    Node的SearchNode()

    如果索引和传入索引相等,返回当前Node对象

    当this对象的左子节点不为空,当左子节点索引等于传入索引,返回当前对象的子节点

    否则继续对当前对象的左子节点搜索,搜索结果赋值给temp,当temp不为空,返回temp

    对右子节点的逻辑同上

    否则返回为空

    思路:从上向下搜索,顺序为前序

    Node *Node::SearchNode(int nodeIndex)
    {
        if (this->index == nodeIndex)
        {
            return this;
        }
    
        Node *temp = NULL;
        if (this->pLChild != NULL)
        {
            if (this->pLChild->index == nodeIndex)
            {
                return this->pLChild;
            }
            else
            {
                temp = this->pLChild->SearchNode(nodeIndex);
                if (temp != NULL)
                {
                    return temp;
                }
            }
        }
    
        if (this->pRChild != NULL)
        {
            if (this->pRChild->index == nodeIndex)
            {
                return this->pRChild;
            }
            else
            {
                temp = this->pRChild->SearchNode(nodeIndex);
                if (temp != NULL)
                {
                    return temp;
                }
            }
        }
    
        return NULL;
    }

    添加结点

    传入索引,direction=0添加左子节点,direction=1添加右子节点,传入pNode参数

    先搜索结点并保存在temp中,temp为空返回错误

    申请内存给node,为空返回错误

    将pNode的index和data分别赋值给node的index和data

    node的pParent指针指向temp,temp为指定索引的父节点

    direction=0,将temp的pLChild指针指向node

    direction=1,将temp的pRChild指针指向node

    bool Tree::AddNode(int nodeIndex, int direction, Node* pNode)
    {
        Node *temp = SearchNode(nodeIndex);
        if (temp == NULL)
        {
            return false;
        }
    
        Node *node = new Node();
        if (node == NULL)
        {
            return false;
        }
        node->index = pNode->index;
        node->data = pNode->data;
        node->pParent = temp;
    
        if (direction == 0)
        {
            temp->pLChild = node;
        }
    
        if (direction == 1)
        {
            temp->pRChild = node;
        }
    
        return true;
    }

    删除结点

    传入nodeIndex,pNode参数

    搜索结点保存在temp

    temp为空,返回错误

    pNode不为空,将的temp的data赋值给pNode的data,做返回值使用

    调用Node的DeleteNode方法,参见销毁树

    bool Tree::DeleteNode(int nodeIndex, Node* pNode)
    {
        Node *temp = SearchNode(nodeIndex);
        if (temp == NULL)
        {
            return false;
        }
    
        if (pNode != NULL)
        {
            pNode->data = temp->data;
        }
    
        temp->DeleteNode();
        return true;
    }

    前序遍历

    调用了Node的PreorderTraversal()

    void Tree::PreorderTraversal()
    {
        m_pRoot->PreorderTraversal();
    }

     

     Node的PreorderTraversal()

    先输出根节点

    左子结点不为空递归,输入当前结点

    右子节点不为空递归,输入当前结点

    递归的算法最好对着源码打断点,就能看懂了

    void Node::PreorderTraversal()
    {
        cout << this->index<<"  "<<this->data << endl;
        if (this->pLChild != NULL)
        {
            this->pLChild->PreorderTraversal();
        }
        if (this->pRChild != NULL)
        {
            this->pRChild->PreorderTraversal();
        }
    }

    中序遍历和后序遍历

    中序遍历:左根右

    后序遍历:左右根

    void Tree::InorderTraversal()
    {
        m_pRoot->InorderTraversal();
    }
    
    void Tree::PostorderTraversal()
    {
        m_pRoot->PostorderTraversal();
    }

     

    逻辑与前序遍历代码相似

    this->index和this->data就是根节点的内容

    左右结点进行递归

    void Node::InorderTraversal()
    {
        if (this->pLChild != NULL)
        {
            this->pLChild->InorderTraversal();
        }
        cout << this->index << "  " << this->data << endl;
        if (this->pRChild != NULL)
        {
            this->pRChild->InorderTraversal();
        }
    }
    
    void Node::PostorderTraversal()
    {
        if (this->pLChild != NULL)
        {
            this->pLChild->PostorderTraversal();
        }
        if (this->pRChild != NULL)
        {
            this->pRChild->PostorderTraversal();
        }
        cout << this->index << "  " << this->data << endl;
    }

     

    posted @ 2018-08-09 13:05 Rest探路者 阅读(...) 评论(...) 编辑 收藏
    展开全文
  • 单向链表c++实现

    2020-03-07 20:05:11
    单向链表的结构 单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)...其中节点指针next指向节点类型变量,从而实现链表的连接 设置链表类如下,包含一节点指针head class...

    单向链表的结构

    单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
    在这里插入图片描述
    设置节点类如下:

    class Node{
    	int item;
    	Node* next;
    };
    

    其中节点指针next指向节点类型变量,从而实现链表的连接
    设置链表类如下,包含一节点指针head

    class SingleLink{
    public:
    	SingleLink();
    	~SingleLink();
    	Node* head;
    	void append(int);
    };
    

    新建一个链表,初始化如下:

    SingleLink::SingleLink(){
    	head = new Node();
    	head->item = 0;
    	head->next = NULL;
    }
    

    在head = new Node()时,指针head便有了个新的对象
    在这里插入图片描述

    详解链表尾插法实现原理

    1.插入第一个元素,指针n有个新对象

    Node* n = new Node();
    	n->item = 11;
    	n->next = NULL;
    

    在这里插入图片描述
    指针next等于指针n,表示next的指向与n的指向一致

    head->next = n;
    n->next = NULL;
    

    在这里插入图片描述
    2.插入第二个元素,即n又有了个新对象

    	Node* n = new Node();
    	n->item =22;
    	n->next = NULL;
    

    在这里插入图片描述
    令临时指针temp指向head的指向,循环后,temp的指向指向链表0号位中next的指向,过程图如下:

    temp = head;
    while(temp->next!=NULL){
    temp =temp->next;
    

    在这里插入图片描述
    在这里插入图片描述

    temp->next = n;
    

    完成第二个节点的尾插
    在这里插入图片描述
    以此类推,插第n个时,temp指针要指n下,所以链表中append指令时间复杂度为O(n)

    具体代码

    实现单向链表基本操作代码如下,包含删除,插入,遍历等功能

    // 单链表测试.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    class Node{
    public:
    	Node();
    	~Node();
    public:
    	int item;
    	Node* next;
    };
    Node::Node()
    {
    
    }
    Node::~Node()
    {
    
    }
    class SingleLink{
    public:
    	SingleLink();
    	~SingleLink();
    	Node* head;
    	bool is_Linkempty();
    	void append(int);
    	void travel();
    	int get_length();
    	void add(int);
    	void insert(int pos,int item);
    	int search(int item);
    	void delete_last();
    	void delete_first();
    	void deleta_pos(int pos);
    	void remove(int item);
    };
    SingleLink::SingleLink(){
    	head = new Node();
    	head->item = 0;
    	head->next = NULL;
    }
    SingleLink::~SingleLink(){
    
    }
    bool SingleLink::is_Linkempty(){
    	return head->next == NULL;
    }
    void SingleLink::append(int item){
    	Node* n = new Node();
    	Node* temp;
    	n->item = item;
    	n->next = NULL;
    	if (head->next == NULL)
    	{
    		head->next = n;
    		n->next = NULL;
    		return;
    	}
    	//容易错啊
    	//temp = head->next;
    	//while(temp!=NULL){
    	//	temp = temp->next;
    	//}
    	//temp->next= n;
    	temp = head;
    	while(temp->next!=NULL){
    		temp =temp->next;
    	}
    	//只有这样才能改变这个节点的指针域的值啊
    	temp->next = n;
    }
    int SingleLink::get_length(){
    	int size = 0;
    	//数数用的游标
    	Node*cur = head;
    	while(cur->next!=NULL){
    		size++;
    		cur=cur->next;
    	}
    	return size;
    
    }
    void SingleLink::travel(){
    	//游标
    	Node*cur = head->next;
    	while(cur!=NULL){
    		cout<<cur->item<<"->";
    		cur = cur->next;
    	}
    	cout<<"Null"<<endl;
    }
    void SingleLink::add(int item){
    	Node* n = new Node;
    	n->item = item;
    	n->next = head->next;
    	head->next = n;
    }
    void SingleLink::insert(int pos,int item){
      //pos是0到length-1
    	if (pos<=0)
    	{
    		add(item);
    		return;
    	}
    	if (pos>=(this->get_length()))
    	{
    		append(item);
    		return;
    	}
    	Node* cur1 = head;
    	Node* cur2 = head;
    	for (int j =0;j<=pos-1;j++)
    	{
    		cur1 = cur1->next;
    		cur2 = cur2->next;
    	}
    	cur2 = cur2->next;
    	Node* n = new Node();
    	n->item = item;
    	n->next = cur2;
    	cur1->next = n;
    }
    int SingleLink::search(int item){
    	//搜索链表中第一个出现该数字的下标
    	int pos = 0;
    	Node* cur = head;
    	while(cur->next!=NULL){
    		cur = cur->next;		
    		if(cur->item ==item)
    		{
    			return pos;			
    		}
    		pos++;
    	}
    	cout<<"没有该数据"<<endl;
    	return -1;	
    }
    void SingleLink::delete_last(){
    	if (get_length()<=0)
    	{
    		return;
    	}
    	if (get_length()==1)
    	{
    		head->next = NULL;
    		return;
    	}
    	/*if(get_length()-2>=0)*/
    	Node* cur1 = head;
    	for(int i = 0;i<=get_length()-2;i++){
    		cur1 = cur1->next;
    	}
    	//Node* cur2 = cur1->next;
    	//free(cur2);
    	cur1->next = NULL;
    	
    }
    void SingleLink::delete_first(){
    	if (get_length()<=0)
    	{
    		return;
    	}
    	if (get_length()==1)
    	{
    		head->next = NULL;
    		return;
    	}
    	Node* cur1 = head->next;	
    	head->next = cur1->next;
    }
    void SingleLink::deleta_pos(int pos){
    	if (pos>=get_length()-1)
    	{
    		delete_last();
    		return;
    	}
    	if (pos<=0)
    	{
    		delete_first();
    		return;
    	}
    	Node* cur = head;
    	for(int j=0;j<pos;j++)
    	{
    		cur = cur->next;
    	}
    	//循环后是3个节点中最前的节点
    	Node*cur1 = cur->next;	
    	cur->next = cur1->next;
    }
    void SingleLink::remove(int item){
    	//删除第一次出现的元素
    	if (search(item)==-1)
    	{
    		return;
    	}
    	deleta_pos(search(item));
    }
    int main()
    {
    	cout<<"hello world"<<endl;
    	SingleLink* L = new SingleLink();
    	L->add(2);
    	L->append(1);
    	L->append(2);
    	L->append(5);
    	L->travel();
    	cout<< L->get_length()<<endl;
    	L->add(70);
    	L->travel();
    	L->insert(1,100);
    	L->travel();
    	cout<< L->search(70)<<endl;
    	cout<< L->get_length()<<endl;
    	
    	L->remove(12);
    	L->remove(2);
    	L->travel();
    	system("pause");
    	return 0;
    }
    
    
    

    在这里插入图片描述

    小结

    单链表是数据结构与算法的基础,特记录自己的学习思路

    展开全文
  • 双向链表C++实现

    2017-05-23 08:26:00
    双向链表实现,通过C++实现 #ifndef LinkList_hpp #define LinkList_hpp typedef struct Node{ int data; Node* next; Node* pre; }Node; class LinkList{ private: Node *head; Node *tail; int l...
  • 双向链表C++实现代码

    2019-09-06 16:26:32
    1、双向链表和单链表 单链表是在每个节点只有一个指向下一节点的指针,所以遍历时候需要从头开始,而双向链表的每个节点有两个指针,一个指向...单链表C++实现 #include <string> #include <iostream>...
  • 循环链表 c++实现

    2019-07-12 16:53:25
    问题描述: 已知n个人,围坐一个圆桌周围。...循环链表实现: // letcode.cpp : 定义控制台应用程序的入口点。 // #include"stdafx.h" #include<iostream> #include<stdio.h> #i...
  • 掌握二叉链表上二叉树的基本运算的实现 二 实验内容 1. 实现二叉树的层次递进 2. 将一颗二叉树的所有左右子树进行交换 三 实验与算法分析 二叉树的遍历 二叉树的层次遍历采用的是队列本题用一个一维数组来代替队列...
  • 单向链表C++实现

    2018-05-25 09:44:24
    单向链表: 从字面上理解,那就是“单向”+“链表”,表明这种数据结构是有方向性的,并且只有一个方向。另外,“链表”表明这种数据结构是一种链式存储结构,它不同于线性表的顺序存储结构。链表的相邻元素在物理...
  • 双向链表c++实现

    千次阅读 2018-06-08 18:07:36
    cout 链表为空,oop!!" ; return 0; } else { if (ptr->doublelink_getlength(ptr) == 1) { ptr->root->next = NULL; ptr->length--; } else { node* deletenode = root->next; for ...
  • 【反转链表 c++实现

    2020-09-11 19:49:38
    【题目描述】输入链表的头结点,反转链表后输出链表的所有元素; struct ListNode { int val; struct ListNode *next; }; 【解题思路】 1)定义三个辅助指针和一个用于表示翻转链表头结点的指针; 2)node指向...
  • 双向循环链表C++实现

    2019-08-20 17:08:39
    // 清空链表链表仍存在,但链表中无元素,成为空链表(头指针和头节点仍然存在) // 算法思路:依次释放所有节点,并将头结点的指针域设置为空 Status ClearDuCirList(DuCirLinkList &L); // 双向循环链表的表长 ...
  • 代码实现 有两种思路: 比较直观的想法,两个链表长度不一样,我就从前往后截取到一样的长度,然后去遍历。 两个链表长度不一样,我使得两个补齐成一样的长度,然后遍历。 直观图示: 方法一: /** * Definition...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,735
精华内容 3,094
关键字:

链表c++实现

c++ 订阅