基于模板编程实现了一个泛型的链表,并通过函数实现了几个特定功能
简单估算了一下,去掉测试代码,大约200多行

链表类的属性如下:

  • head: 头结点
  • tail: 尾节点
  • size: 节点个数

链表类约定如下:
链表没有空的头节点(哑节点)
链表尾节点tail的next属性赋值nullptr
当链表为空时,head和tail都赋值nullptr
当链表仅有一个元素时,head==tail

链表类的方法如下:

  • empty(): 判断链表是否为空
  • getSize(): 获取链表节点个数
  • clear(): 清空链表
  • display(): 显示链表所有元素
  • front(): 返回链表头结点
  • back(): 返回链表尾节点
  • popFront(): 删除头节点
  • popBack(): 删除尾节点
  • pushFront(): 插入头节点
  • pushBack(): 插入尾节点

另外,专门实现了如下函数:

  • split(): 根据链表元素为奇数值还是偶数值,拆分链表
  • findCommonElements(): 寻找两个链表的共有元素
  • removeDuplicates(): 链表元素去重
  • mergeAndDelete(): 合并两个链表,并对元素去重
  • findKtyFromEnd(): 找到链表倒数第k个元素(作业要求不能使用尾节点)

以下是具体的代码实现:

#ifndef LINKEDLIST_H
#define LINKEDLIST_H

#include <iostream>
using namespace std;

template<typename T>
struct Node {
    T data;
    Node* next;
    Node(const T& newData) : data(newData), next(nullptr) {}
};

template<typename T>
class List {
public:
    Node<T>* head;
    Node<T>* tail;
    int size;

    List() : head(nullptr), tail(nullptr), size(0) {}

    ~List() { clear(); }

    bool empty() const {
        return head == nullptr;
    }

    int getSize() const {
        return size;
    }

    void clear() {
        while(!empty()) {
            popFront();
        }
    }

    void display() const {
        Node<T>* cur = head;
        while(cur != nullptr) {
            cout<<cur->data<<" ";
            cur = cur->next;
        }
        cout<<endl;
    }

    const T& front() const {
        if(head == nullptr) cout<<"the list is empty"<<endl;
        return head->data;
    }

    const T& back() const {
        if(tail == nullptr) cout<<"the list is empty"<<endl;
        return tail->data;
    }

    void popFront() {
        if(empty()) return;

        Node<T>* tmp = head;
        head = head->next;
        delete tmp;

        if(head == nullptr) {
            tail = nullptr;
        }

        size--;
    }

    void popBack() {
        if(empty()) return;

        if(head == tail) {
            delete head;
            head = tail = nullptr;
        } else {
            Node<T>* node = head;
            while(node->next != tail)
                node = node->next;
            delete tail;
            tail = node;
            tail->next = nullptr;
        }

        size--;
    }

    void pushFront(const T& data) {
        Node<T>* newNode = new Node<T>(data);
        newNode->next = head;
        head = newNode;

        if(tail == nullptr) {
            tail = newNode;
        }

        size++;
    }

    void pushBack(const T& data) {
        Node<T>* newNode = new Node<T>(data);
        
        if(tail == nullptr) {
            head = newNode;
            tail = newNode;
        } else {
            tail->next = newNode;
            tail = tail->next;
        }
        size++;
    }
};

#endif 
void split(List<int>& L, List<int>& oddList, List<int>& evenList) {
    Node<int>* cur = L.head;

    while(cur != nullptr) {
        if(cur->data % 2 == 1) 
            oddList.pushBack(cur->data);
        else 
            evenList.pushBack(cur->data);
        cur = cur->next;
    }
}
template<typename T>
void findCommonElements(const List<T>& L1, const List<T>& L2, List<T>& L3) {
    Node<T>* cur1 = L1.head;
    Node<T>* cur2 = L2.head;

    while(cur1 != nullptr && cur2 != nullptr) {
        if(cur1->data == cur2->data) {
            L3.pushBack(cur1->data);
            cur1 = cur1->next;
            cur2 = cur2->next;
        } else if(cur1->data < cur2->data) {
            cur1 = cur1->next;
        } else {
            cur2 = cur2->next;
        }
    }
}
template<typename T>
void removeDuplicates(List<T>& L) {
    if(L.empty()) return;

    Node<T>* cur = L.head;

    while(cur->next != nullptr) {
        if(cur->data == cur->next->data) {
            Node<T>* tmp = cur->next;
            cur->next = cur->next->next;
            delete tmp;
        } else {
            cur = cur->next;
        }
    }
}
template<typename T>
void mergeAndDelete(List<T>& L1, List<T>& L2) {
    Node<T>* cur1 = L1.head;
    Node<T>* cur2 = L2.head;
    Node<T>* pre1 = nullptr;

    while(cur1 != nullptr && cur2 != nullptr) {
        if(cur1->data < cur2->data) {
            pre1 = cur1;
            cur1 = cur1->next;
        } else if(cur1->data == cur2->data) {
            Node<T>* tmp = cur2;
            cur2 = cur2->next;
            delete tmp;
        } else {
            if(pre1 != nullptr) {
                pre1->next = cur2;
            } else {
                L1.head = cur2;
            }

            pre1 = cur2;
            cur2 = cur2->next;
            pre1->next = cur1;
        }
    }

    if(cur2 != nullptr) {
        if(pre1 != nullptr) {
            pre1->next = cur2;
        } else {
            L1.head = cur2;
        }
    }

    //L2.clear();
    L2.head = nullptr;
}
template<typename T>
bool findKthFromEnd(List<T>& L, int k, T& result) {
    if(L.empty() || k <= 0) return false;

    Node<T>* fast = L.head;
    Node<T>* slow = L.head;

    for(int i = 0; i < k - 1; ++i) {
        if(fast->next != nullptr) {
            fast = fast->next;
        } else {
            return false;
        }
    }

    while(fast->next != nullptr) {
        fast = fast->next;
        slow = slow->next;
    }

    result = slow->data;
    return true;
}
最后修改:2024 年 04 月 10 日
如果觉得我的文章对你有用,请随意赞赏