线性表(2)--链表模拟

线性表(2)--链表模拟

线性表--链表的类实现:

简要介绍:
    物理存储单元非连续、非顺序的存储结构,逻辑结构,由一系列的节点组成
节点:由指针域和数据域组成
分类:单向链表、静态链表、双向链表、循环链表

优点:
    插入与删除快,大小可变不用去确定
缺点:
    与顺序表相比操作复杂,查找较差,找数必需从头开始找

//------------------------------------------------------
//-------------链表的模拟实现:---------------------
Node.h
#ifndef NODE_H
#define NODE_H

class Node{

public:
    int data;//int数据域, 这里可以为任意类型数据域,如Coordinate类、double.....
    Node *next;//指针域
    void printNode() const;
};

#endif

Node.cpp
#include"Node.h"
#include<iostream>
using namespace std;

void Node::printNode() const{
    cout << data << endl;
}


List.h
#ifndef LIST_H
#define LIST_H
//-------------------
#include"Node.h"
//template <typename T>
class List{

public:
    List();//创建线性表
    ~List();//销毁线性表
    void clearList();//清除
    bool listEmpty();//判空
    int listLength() const;//线性表长度
    bool getElement(int i, Node *pNode);//获取指定元素
    int locElement(Node *pNode);//寻找第一个满足e数据元素的位序
    bool priorElement(Node *pCurrentNode, Node *preElem);//获得前驱
    bool nextElement(Node *pCurrentNode, Node *nextElem);//获得后驱
    void listTraverse();//遍历
    bool listInsert(int i, Node *pNode);//在i位置插入元素e
    bool listDelete(int i, Node *pNode);//删除第i个位置
    bool listInsertHead(Node *pNode);//在第一个节点前插入一个节点
    bool listInsertTail(Node *pNode);//在末尾插入节点
    
private:
    Node *m_pList;
    int m_iLength;
};


#endif LIST_H


List.cpp
#include"List.h"
#include<iostream>
using namespace std;
//----------------------

List::List(){//初始化

    m_pList = new Node;//这个申请的节点并不算在当前链表之中(1)
    //m_pList->data = 0;//数据域
    m_pList->next = NULL;//指针域
    m_iLength = 0;
}
List::~List(){
    
    clearList();//清空链表
    delete m_pList;//释放(1)中节点
    m_pList = NULL;
}

void List::clearList(){
    
    Node *currentNode = m_pList->next;
    while(currentNode != NULL){
        Node * t = currentNode->next;
        delete currentNode;
        currentNode = t;
    }
    m_pList->next = NULL;
    
    m_iLength = 0;
}
bool List::listEmpty(){
    return 0 == m_iLength ? true : false;
}
int List::listLength() const{
    return m_iLength;
}

bool List::getElement(int i, Node *pNode){
    
    if(i < 0 || i >= m_iLength){
        return false;
    }
    
    Node *currentNode = m_pList;
    Node *currentNodeBefore = NULL;
    for(int j = 0; j <= i; j++){//多循环了一次,即删除的节点为currentNode!
    
        currentNodeBefore = currentNode;
        currentNode = currentNode->next;
    }
    pNode->data = currentNode->data;
    return true;
}

int List::locElement(Node *pNode){
    
    Node *currentNode = m_pList;
    int count = 0;
    while(currentNode != NULL){
        //头节点head的第一个数据域没有意义,0号节点应该是我们要找的第一个节点,即head的后一个节点
        currentNode = currentNode->next;
        if(currentNode->data == pNode->data){
            return count;
        }
        count++;
    }
    return -1;
    
}

bool List::priorElement(Node *pCurrentNode, Node *preElem){
    
    Node *currentNode = m_pList;
    Node *currentNodeBefore = NULL;
    
    while(currentNode->next != NULL){
        //头节点head的第一个数据域没有意义,0号节点应该是我们要找的第一个节点,即head的后一个节点
        currentNodeBefore = currentNode;
        currentNode = currentNode->next;
        if(currentNode->data == pCurrentNode->data){
            
            if(currentNodeBefore == m_pList){//head节点后的第一个节点,我们也是认为没有前驱的
                cout << "没有前驱" << endl;
                return false;
            }
            preElem->data = currentNodeBefore->data;
            return true;
        }
    }
    return false;
}


bool List::nextElement(Node *pCurrentNode, Node *nextElem){
    
    Node *currentNode = m_pList;
        while(currentNode->next != NULL){

        currentNode = currentNode->next;
        if(currentNode->data == pCurrentNode->data){
            
            nextElem->data = currentNode->next->data;
            return true;
        }
    }
    cout << "没有后继" << endl;
    return false;
}


void List::listTraverse(){
    
    Node *currentNode = m_pList;
    while(currentNode->next != NULL){
        
        currentNode = currentNode->next;
        currentNode->printNode();//head后面的才算第一个节点
    }
    
}


bool List::listInsert(int i, Node *pNode){
    
    if(i < 0 || i > m_iLength){
        return false;
    }
    
    Node *currentNode = m_pList;
    for(int j = 0; j < i ; j++){
        currentNode = currentNode->next;
    }
    
    Node *tNode = new Node;//新生节点,堆中申请内存
    if(tNode == NULL){
        return false;
    }
    tNode->data = pNode->data;
    tNode->next = currentNode->next;//currentNode原先指向的节点赋给tNode指向的下个节点
    currentNode->next = tNode;//currentNode指向tNode
    
    m_iLength++;
    return true;
}

bool List::listDelete(int i, Node *pNode){
    
    if(i < 0 || i >= m_iLength){
        return false;
    }
    
    Node *currentNode = m_pList;
    Node *currentNodeBefore = NULL;
    for(int j = 0; j <= i; j++){//多循环了一次,即删除的节点为currentNode!
    
        currentNodeBefore = currentNode;
        currentNode = currentNode->next;
    }
    
    currentNodeBefore->next = currentNode->next;//删除节点
    pNode->data = currentNode->data;
    delete currentNode;
    currentNode = NULL;
    
    
    m_iLength--;
    return true;
}

bool List::listInsertHead(Node *pNode){
    
    Node *t = m_pList->next;//临时节点
    Node *tNode = new Node;//新生节点,堆中申请内存
    if(tNode == NULL){
        return false;
    }
    tNode->data = pNode->data;//新生节点的数据域
    m_pList->next = tNode;//m_pList指向新生节点,即 第一个节点
    tNode->next = t;//tNode指向 m_pList原先指向的节点
    m_iLength++;
    return true;
}


bool List::listInsertTail(Node *pNode){
    
    Node *currentNode = m_pList;
    while(currentNode->next != NULL){
        
        currentNode = currentNode->next;
    }
    
    Node *tNode = new Node;//新生节点
    if(tNode == NULL){
        return false;
    }
    tNode->data = pNode->data;
    tNode->next = NULL;
    currentNode->next = tNode;
    m_iLength++;
    return true;
    
}

demo.cpp
#include"List.h"
#include"Coordinate.h"
#include<iostream>
//#include<string.h>
//#include<stdlib.h>
using namespace std;
int main(){
    //测试
    Node node1;//head
    node1.data = 2;
    Node node2;//tail
    node2.data = 4;
    Node node3;
    node3.data = 3;
    Node node4;
    node4.data = 6;
    
    List *list = new List;
    
    list->listInsertHead(&node1);
    list->listInsertTail(&node2);
    list->listInsert(0,&node3);
    list->listInsert(1,&node4);
    cout << "遍历:" << endl;
    list->listTraverse();
    
    Node t;
    
    list->priorElement(&node1,&t);
    cout << node1.data << " 的前驱为:" << t.data << endl;
    list->nextElement(&node1,&t);
    cout << node1.data << " 的后继为:" << t.data << endl;
    
    list->listDelete(0,&t);
    cout << "删除的第一个节点:" << t.data << endl << endl;
    cout << "删除后遍历:" << endl;
    list->listTraverse();
    
    delete list;
    list = NULL;
    
    system("pause");
    return 0;
} 

//控制台运行结果:
遍历:
3
6
2
4
2 的前驱为:6
2 的后继为:4
删除的第一个节点:3

删除后遍历:
6
2
4

//---------------------------------------------------------------------------

//-------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值