c++链表简单功能实现

这周主要学习了链表这种数据结构,基本实现了链表的各项功能,也算是对类的创建以及指针的操作有了进一步的了解,下面给出实现的链表的代码。

1、链表节点

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED

#include <iostream>
#include <iomanip>

using namespace std;

class node {
    friend class linklist;
  public:
    // 无参数构造函数
    node ( void );
    // 有参数构造函数,给定节点值
    node ( double );
    // 有参数构造函数,给定节点值及其地址
    node ( double, node* );
    // 复制构造函数
    node ( const node & );
    // 赋值运算符重载
    node &operator= ( const node & );
    // 析构函数
    ~node();
    // 设置节点值
    void setdate ( const double & );
    // 取节点值
    double getdate() const;
    // 设置节点地址
    void setpnext ( node * );
    // 获取节点地址
    node *getpnext() const;
    // 打印节点
    void printnode() const;
  private:
    double date;
    node *pnext;
};

// 默认参数为零,指针为空 node::node() : date ( 0 ), pnext ( NULL ) { }
// 默认指针为空 node::node ( double num ) : date ( num ), pnext ( NULL ) { } node::node ( double num, node *node1 ) : date ( num ), pnext ( node1 ) { } node::node ( const node &node1 ) : date ( node1.date ), pnext ( NULL ) { } node &node::operator= ( const node &node1 ) { date = node1.date; pnext = NULL; return *this; } node::~node() { } void node::setdate ( const double & num ) { date = num; } double node::getdate() const { return date; } void node::setpnext ( node *node1 ) { pnext = node1; } node *node::getpnext() const { return pnext; } void node::printnode() const { cout << setw ( 10 ) << "date:" << setw ( 10 ) << date << setw ( 10 ) << "pnext:" << setw ( 10 ) << pnext << endl; } #endif // NODE_H_INCLUDED

2、链表功能

#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED

#include <iostream>
#include <iomanip>
#include "node.h"

using namespace std;

class linklist {
  public:
    // 无参数构造函数,创建一个空链表
    linklist();
    // 有参数构造函数,创建含一个节点的链表
    linklist ( double );
    // 复制构造函数
    linklist ( const linklist& );
    // 重载复制运算符
    linklist &operator= ( const linklist& );
    // 析构函数
    ~linklist();
    // 获取链表头节点
    node *gethead() const;
    // 获取链表长度
    int lengthlist() const;
    // 获取指定位置节点数值,返回数值
    double getvalue ( int ) const;
    // 获取指定位置节点地址,返回节点地址
    node *getnode ( int ) const;
    // 改变特定位置节点值
    void changevalue ( int, double );
    // 首部插入节点
    void insertliststart ( double );
    // 删除首节点
    void removeliststart();
    // 尾部插入节点
    void insertlistend ( double );
    // 移除尾部节点
    void removelistend();
    // 特定位置插入节点
    void insertlist ( int, double );
    // 移除指定位置节点
    void removelist ( int );
    // 链表反转(比较废时的计算方法,计算复杂度n^2)
    void reverselist();
    // 链表反转(计算时间缩短,计算复杂度n)
    void reverselist2();
    // 打印链表
    void printlist() const;
  private:
    node *head;
};

linklist::linklist() : head ( NULL ) {
}

linklist::linklist ( double num ) : head ( new node ( num ) ) {
}

linklist::linklist ( const linklist &list1 ) : head ( NULL ) {
    node *temp = list1.gethead();
    if ( NULL != temp ) {
        head = new node ( temp->getdate() );  // 创建表头
        node *temp1 = head;
        while ( NULL != temp->getpnext() ) {  // 遍历list1,创建链表
            temp = temp->getpnext();
            temp1->setpnext ( new node ( temp->getdate() ) );
            temp1 = temp1->getpnext();
        }
    }
}

linklist &linklist::operator= ( const linklist &list1 ) {
    node *temp = list1.gethead();
    if ( NULL == temp ) {  // 空链表
        head = NULL;
    } else {  // 非空链表
        head = new node ( temp->getdate() );  // 创建表头
        node *temp1 = head;
        while ( NULL != temp->getpnext() ) {  // 遍历list1,创建链表
            temp = temp->getpnext();
            temp1->setpnext ( new node ( temp->getdate() ) );
            temp1 = temp1->getpnext();
        }
    }
    return *this;
}

linklist::~linklist() {
    if ( NULL != head ) {  // 非空链表
        node *temp = NULL;
        while ( NULL != head ) {  // 遍历链表,逐个释放
            temp = head;
            head = head->getpnext();
            delete temp;
        }
        delete head;
    }
}

node *linklist::gethead() const {
    return head;
}

int linklist::lengthlist() const {
    node *temp = head;
    int countlist = 0;
    while ( NULL != temp ) {  // 遍历非空链表
        temp = temp->getpnext();
        countlist++;
    }
    return countlist;
}

double linklist::getvalue ( int pos ) const {
    int length_list = lengthlist();  // 获取链表长度
    if ( 0 == length_list ) {  // 空链表
        cout << "the list is empty" << endl;
        return 0;
    } else {  // 非空链表
        if ( pos < 1 ) {  // 给定位置为负值时,返回链表头部节点值
            pos = 1;
            cout << "output the first node's value of the list" << endl;
        }
        if ( pos > length_list ) {  // 给定位置超出链表长度,返回链表尾部节点值
            pos = length_list;
            cout << "output the last node's value of the list" << endl;
        }
        node *temp = head;
        for ( int countlist = 1; countlist < pos; countlist++ ) {  // 获取指定节点位置值
            temp = temp->getpnext();
        }
        return temp->getdate();
    }
}

node *linklist::getnode ( int pos ) const {
    int length_list = lengthlist();
    if ( 0 == length_list ) {  // 空链表
        cout << "the list is empty" << endl;
        return NULL;
    } else {  // 非空链表
        if ( pos < 1 ) {
            pos = 1;
            cout << "output the first node's value of the list" << endl;
        }
        if ( pos > length_list ) {
            pos = length_list;
            cout << "output the last node's value of the list" << endl;
        }
        node *temp = head;
        for ( int countlist = 1; countlist < pos; countlist++ ) {
            temp = temp->getpnext();
        }
        return temp;
    }
}

void linklist::changevalue ( int pos, double num ) {
    int length_list = lengthlist();
    if ( 0 == length_list ) {  // 空链表
        cout << "the list is empty" << endl;
    } else {  // 非空链表
        if ( pos < 1 ) {  
            cout << "exceed the range of list,operate false" << endl;
        } else if ( pos > length_list ) {
            cout << "exceed the range of list,operate false" << endl;
        } else {
            node *temp = getnode ( pos );
            temp->setdate ( num );
        }
    }
}

void linklist::insertliststart ( double num ) {
    if ( NULL == head ) {  // 空链表
        head = new node ( num );
    } else {  // 非空链表
        node *temp = head;
        head = new node ( num );
        head->setpnext ( temp );
    }
}

void linklist::removeliststart() {
    if ( NULL == head ) {  // 空链表
        cout << "the list is empty" << endl;
    } else {  // 非空链表
        node *temp = head;
        head = head->getpnext();
        delete temp;
    }
}

void linklist::insertlistend ( double num ) {
    if ( NULL == head ) {  // 空链表
        head = new node ( num );
    } else {  // 非空链表
        node *temp = head;
        node *newnode = new node ( num );
        while ( NULL != temp->getpnext() ) {
            temp = temp->getpnext();
        }
        temp->setpnext ( newnode ) ;
    }
}

void linklist::removelistend() {
    if ( NULL == head ) {  // 空链表
        cout << "the list is empty" << endl;
    } else if ( NULL == head->getpnext() ) { // 非空链表,只有一个节点
        node *temp = head;
        head = head->getpnext();
        delete temp;
    } else {  // 非空链表,多个节点
        int length_list = lengthlist();
        node *temp = getnode ( length_list - 1 );
        node *deletenode = temp->getpnext();
        temp->setpnext ( NULL );
        delete deletenode;
    }
}

void linklist::insertlist ( int pos, double num ) {
    int length_list = lengthlist();
    if ( pos <= 1 ) {  // 给定位置为负值,或者小于1时,在链表开头插入新节点
        insertliststart ( num );
        if ( pos < 0 ) {
            cout << "insert the value at the start of the list" << endl;
        }
    } else if ( pos > length_list ) { // 给定位置超出链表长度时,在链表尾部插入新节点
        insertlistend ( num );
        cout << "insert the value at the end of the list" << endl;
    } else {  // 在链表中间位置插入新节点
        node *newnode = new node ( num );
        node *temp = getnode ( pos - 1 );
        newnode->setpnext ( temp->getpnext() );
        temp->setpnext ( newnode );
    }
}

void linklist::removelist ( int pos ) {
    int length_list = lengthlist();
    if ( pos <= 1 ) {  // 给定位置为负值或小于1时,移除头部节点
        removeliststart();
        if ( pos < 0 ) {
            cout << "remove the first node of the list" << endl;
        }
    } else if ( pos > length_list ) {  // 给定位置超出链表长度,移除尾部节点
        removelistend();
        cout << "remove the last node of the list" << endl;
    } else { // 移除中间位置节点
        node *temp = getnode ( pos - 1 );
        node *deletenode = temp->getpnext();
        temp->setpnext ( deletenode->getpnext() );
        delete deletenode;
    }
}

void linklist::reverselist() {
    if ( NULL != head ) { // 非空链表
        if ( NULL != head->getpnext() ) {  // 链表节点数大于1
            int list_length = lengthlist();
            int pos;
            node *tempend = getnode ( list_length );  // 获取尾部节点地址
            node *temp = NULL;
            node *tempnext = NULL;
            for ( pos = list_length - 1; pos > 0; pos-- ) {  // 从尾部开始逐个反转链表
                temp = head;
                for ( int countlist = 1; countlist < pos; countlist++ ) { // 获取待反转位置节点前一个节点位置
                    temp = temp->getpnext();
                }
                tempnext = temp->getpnext(); // 链表反转
                tempnext->setpnext ( temp ); // 节点迁移
                temp->setpnext ( NULL );
            }
            head = tempend;  // 设置开始节点位置
        }
    } else { // 空链表
        cout << "the list is empty" << endl;
    }
}

void linklist::reverselist2() {
    if ( NULL != head ) {  // 非空链表
        if ( NULL != head->getpnext() ) {  // 链表节点数为1
            node *temp = head;
            node *temp1 = head->getpnext();
            if ( NULL == temp1->getpnext() ) { // 链表节点数为2
                temp1->setpnext ( temp );
                temp->setpnext ( NULL );
                head = temp1;
            } else {  // 链表节点数目大于2
                temp->setpnext ( NULL );
                node *temp2 = temp1->getpnext();
                while ( NULL != temp2->getpnext() ) {
                    temp1->setpnext ( temp );
                    temp = temp1;
                    temp1 = temp2;
                    temp2 = temp2->getpnext();
                }
                temp1->setpnext ( temp );
                temp2->setpnext ( temp1 );
                head = temp2;
            }
        }
    } else {  // 空链表
        cout << "the list is empty" << endl;
    }
}

void linklist::printlist() const {  
    if ( NULL != head ) {  // 非空链表
        node *temp = head;
        int countlist = 0;
        while ( NULL != temp ) {
            cout << setw ( 5 ) << temp->getdate();
            if ( 0 == ( countlist + 1 ) % 10 ) {
                cout << endl;
            }
            temp = temp->getpnext();
            countlist++;
        }
        cout << endl;
    } else {  // 空链表
        cout << "the list is empty" << endl;
    }
}

#endif // LINKLIST_H_INCLUDED

3、测试函数,各个函数功能使用正常。

#include <iostream>
#include <iomanip>
#include "node.h"
#include "linklist.h"

using namespace std;

int main() {
    linklist list1;
    for ( int i = 1; i < 10; i++ ) {
        list1.insertlistend ( i );
    }
    list1.reverselist2();
    list1.printlist();
    return 0;
}

  

posted @ 2017-11-03 22:38  药否  阅读(1441)  评论(0编辑  收藏  举报