链表

1.关于链表
链表的特点:
    1】数据分散存储            
    2】查询性能没有Vector好            
    3】新增与删除的性能好于Vector    
 
链表的种类:
    单链表    ->由多个节点组成,每一个节点中保存数据和下一个节点的指针;
    循环链表    ->最后一个节点中的指针指向头结点;
    双向链表    ->每个节点多维护一个指针,两个指针分别指向前一个节点和后一个节点,可以从正反两个方向来查找元素;
 
2.实现单链表
头文件:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
                            
#define INDEX_IS_ERROR   -2 // 错误的索引号                                
#define BUFFER_IS_EMPTY  -3 // 缓冲区已空                                
 
 
#include "stdio.h"
#include "windows.h"                                
#include "stdlib.h"
                                
template <class T_ELE>                                
class LinkedList                                
{                                
public:                                
    LinkedList();                            
    ~LinkedList();                            
public:                                
    BOOL  IsEmpty();                        //判断链表是否为空 空返回1 非空返回0    
    void  Clear();                        //清空链表    
    DWORD GetElement(IN DWORD dwIndex,OUT T_ELE& Element);                        //根据索引获取元素    
    DWORD GetElementIndex(IN T_ELE& Element);                        //根据元素获取链表中的索引    
    DWORD Insert(IN T_ELE Element);                        //新增元素    
    DWORD Insert(IN DWORD dwIndex, IN T_ELE Element);                        //根据索引新增元素    
    DWORD Delete(IN DWORD dwIndex);                        //根据索引删除元素    
    DWORD GetSize();                        //获取链表中元素的数量    
private:                                
    typedef struct _NODE                             
    {                            
        T_ELE  Data;                        
        _NODE *pNext;                        
    }NODE,*PNODE;                            
    PNODE GetIndexCurrentNode(DWORD dwIndex);                        //获取索引为dwIndex的指针    
    PNODE GetIndexPreviousNode(DWORD dwIndex);                        //获取索引为dwIndex的前一个节点指针    
    PNODE GetIndexNextNode(DWORD dwIndex);                        //获取索引为dwIndex的后一个节点指针    
private:                                
    PNODE m_pList;                        //链表头指针,指向第一个节点    
    DWORD m_dwLength;                        //元素的数量    
};                                
                                
//无参构造函数 初始化成员                                
template<class T_ELE> LinkedList<T_ELE>::LinkedList()                                
    :m_pList(NULL),m_dwLength(0)                            
{                                
                                
}    
                            
//析构函数 清空元素                                
template<class T_ELE> LinkedList<T_ELE>::~LinkedList()                                
{                                
    Clear();                            
}    
                            
//判断链表是否为空                                
template<class T_ELE> BOOL LinkedList<T_ELE>::IsEmpty()                                
{                                                                
    if(!m_pList){
        return TRUE;
    }
    return FALSE;
}    
                            
//清空链表                                
template<class T_ELE> void LinkedList<T_ELE>::Clear()                                
{                                
    // 1. 判断链表是否为空                            
    if(IsEmpty()){
        return;
    }                            
    // 2. 循环删除链表中的节点    
    while(!m_pList){
        PNODE temp = m_pList;
        m_pList = m_pList->pNext;
        delete temp;
    }
                                
    // 3. 删除最后一个节点并将链表长度置为0    
    m_pList = NULL;
    m_dwLength = 0;
                                
}    
                            
//根据索引获取元素                                
template<class T_ELE> DWORD LinkedList<T_ELE>::GetElement(IN DWORD dwIndex,OUT T_ELE& Element)                                
{                                
    // 1. 判断索引是否有效                            
    if(dwIndex<0 || dwIndex>(m_dwLength-1)){
        return INDEX_IS_ERROR;
    }                            
    // 2. 取得索引指向的节点
    PNODE pElem = m_pList;
    for(int i=0;i<dwIndex;i++){
        pElem = pElem->pNext;            
    }
                                
    // 3. 将索引指向节点的值复制到OUT参数
    memcpy(&Element, pElem, sizeof(T_ELE));
                                
}
                                
//根据元素内容获取索引                                
template<class T_ELE> DWORD LinkedList<T_ELE>::GetElementIndex(IN T_ELE& Element)                                
{                                
    // 1. 判断链表是否为空
    if(IsEmpty()){
        return -1;
    }
                                
    // 2. 循环遍历链表,找到与Element相同的元素    
    PNODE temp = m_pList;
    int i=0;
    while(temp){
        if(temp->Data == Element){
            return i;
        }
        temp = temp->pNext;
        i++;
    }
    return -1;
                                
}
                                
//在链表尾部新增节点                                
template<class T_ELE> DWORD LinkedList<T_ELE>::Insert(IN T_ELE Element)                                
{    
    PNODE newNode = new NODE;
    memcpy(newNode, &Element, sizeof(T_ELE));
    newNode->pNext = NULL;
    //1.判断链表是否为空
    if(IsEmpty()){
        m_pList = newNode;
        m_dwLength++;
        return 1;
    }
 
 
    //2.如果链表不为空
    PNODE temp = m_pList;
    while(temp->pNext){
        temp = temp->pNext;
    }
    temp ->pNext = newNode;
    m_dwLength++;
    return 1;
}        
                        
//将节点新增到指定索引的位置                                
template<class T_ELE> DWORD LinkedList<T_ELE>::Insert(IN DWORD dwIndex, IN T_ELE Element)                                
{                                
                                
    //  1. 判断链表是否为空    
    if(IsEmpty() && dwIndex!=0){
        return -1;
    }                            
    //  2. 判断索引值是否有效
    if(dwIndex<0 || dwIndex>m_dwLength){
        return INDEX_IS_ERROR;
    }
    PNODE newNode = new NODE;
    memcpy(newNode, &Element, sizeof(T_ELE));                            
    //  3. 如果索引为0
    if(dwIndex == 0){
        newNode->pNext = m_pList;
        m_pList = newNode;
    }                            
    //  4. 如果索引为链表尾    
    else if(dwIndex == m_dwLength){
        PNODE temp = m_pList;
        while(temp->pNext){
            temp=temp->pNext;
        }
        temp->pNext = newNode;
        newNode->pNext = NULL;
    }                            
    //  5. 如果索引为链表中    
    else{
        PNODE temp = m_pList;
        for(int i=0;i<dwIndex-1;i++){
            temp = temp->pNext;
        }
        newNode->pNext = temp->pNext;
        temp->pNext = newNode;
    }
 
 
    m_dwLength++;
    return 1;
}
                                
//根据索引删除节点                                
template<class T_ELE> DWORD LinkedList<T_ELE>::Delete(IN DWORD dwIndex)                                
{                                
                                
    //  1. 判断链表是否为空
    if(IsEmpty()){
        return -1;
    }                                
    //  2. 判断索引值是否有效                            
    if(dwIndex<0 || dwIndex>=m_dwLength){
        return INDEX_IS_ERROR;
    }                            
                            
    if(dwIndex == 0){
        if(m_pList->pNext == NULL){
        //  3. 如果链表中只有头节点,且要删除头节点    
            delete m_pList;
            m_pList = NULL;
        }else{
        //  4. 如果要删除头节点    
            PNODE temp = m_pList;
            m_pList = m_pList->pNext;
            delete temp;
        }
        
    }else{
    //  5. 如果是其他情况
        PNODE temp = m_pList;
        for(int i=0;i<dwIndex-1;i++){
            temp = temp->pNext;
        }
        PNODE index = temp->pNext;
        temp->pNext = index->pNext;
        delete index;
    }                            
                            
    m_dwLength--;
    return 1;
                                
}
                                
//获取链表中节点的数量                                
template<class T_ELE> DWORD LinkedList<T_ELE>::GetSize()                                
{                                
    return m_dwLength;                                
}
                                
//获取dwIndex前面节点的地址                                
template<class T_ELE>                                 
LinkedList<T_ELE>::PNODE LinkedList<T_ELE>::GetIndexPreviousNode(DWORD dwIndex)                                
{                                
    // 就是一个循环                            
                                
}    
                            
//获取dwIndex节点的地址                                
template<class T_ELE>                                 
LinkedList<T_ELE>::PNODE LinkedList<T_ELE>::GetIndexCurrentNode(DWORD dwIndex)                                
{                                
    // 就是一个循环                            
                                
}    
                            
//获取dwIndex后面节点的地址                                
template<class T_ELE>                                 
LinkedList<T_ELE>::PNODE LinkedList<T_ELE>::GetIndexNextNode(DWORD dwIndex)                                
{                                
    // 就是一个循环                            
                                
}                                
                                                                                                                                                                                                                                                
#endif

 

测试:
#include "MyLinkedList.h"
 
template <class T_ELE>
void printList(LinkedList<T_ELE>* list){
    for(int i=0;i<list->GetSize();i++){
        T_ELE k;
        list->GetElement(i,k);
        printf("%d\t",k);
    }
    printf("\n");
}
 
void fun(){
    LinkedList<int>* list = new LinkedList<int>();
    //结尾插入
    list->Insert(1);
    list->Insert(2);
    list->Insert(3);
    printList(list);
    //获取索引
    int a = 2;
    int index = list->GetElementIndex(a);
    printf("2的索引是:%d\n", index);
    //索引插入
    int c=0,d=4;
    list->Insert(0, c);
    list->Insert(4, d);
    printList(list);
    //删除
    list->Delete(0);
    list->Delete(2);
    list->Delete(2);
    printList(list);
}
 
void main(){
    fun();
    getchar();
}
结果:
 
 
 
 
posted @ 2019-12-04 09:02  L丶银甲闪闪  阅读(406)  评论(0编辑  收藏  举报