C++描述的数据结构的链表详细教程

数据结构线性表的教程:

一、线性表的基本知识:

  1. 存在唯一的一个被称做第一个
  2. 存在唯一的一个被称作最后一个
  3. 除第一个之外集合中的每个元素只有一个前驱
  4. 除最后一个之外,集合中的每个元素均只有一个后继

5  特点:线性表既有物理上的结构也可以有逻辑上的结构

二、线性表的操作

1.线性表的初始化

2.线性表的遍历

3.线性表插入元素

4.线性表删除元素

 

// 基本操作如下  其实最主要的是思想 不是代码的实现 ,首先带着一种为什么这样操作的思想来看代码 这样会一步步理解 每到一步就应该想到,这步有什么作用,为什么实现这一步。链表的实现其实就是增删改查,首先大致浏览一步函数 有多少个函数,设计多少函数,函数怎么设计,设计之后函数怎么调用 函数怎么传参!

 

#ifndef LIST_H   // 防止其中的数据成员和方法重复  这个文件我命名为 List.h  这样留下面的函数引用
#define LIST_H  
class List  // 添加数据成员 
{
    public:
        List(int size);  // 初始化线性表 
        ~List();  // 析构函数相当与c当中的销毁线性表 
        void ClearList();  // 清空线性表就是释放线性内存 
        bool ListEmpty(); // 判断线性表为空的操作 
        int ListLength(); // 也就是获取线性表的长度将当前线性表的长度作为返回值return 回去  返回的内容实际是m_iLength的值 
        bool GetElem(int i,int *e); // 获取当前的元素 
        int LocateElem(int *e);// 定位一个元素 
        bool PriorElem(int *currentElem,int *preElem);
        bool NextElem(int *currentElem,int *nextElem);
        void ListTraverse();// 遍历线性表 
        bool ListInsert(int i,int *e);
        bool ListDelete(int i,int *e);
            
    private:
        int *m_pList;  // 用这个指针指向一块内存空间,用这个内存存储线性表
        int  m_iSize; // 获取线性表的长度 
        int  m_iLength; //           
        
};
#endif

// 在本次代码实现中我采用了3个程序文件实现:

#include"List.h"   // 引用上面的类    这个文件我命名为 List.cpp
#include<iostream>
 
using namespace std;
List::List(int size)  // 构造函数 
{
 m_iSize=size; // 用户所指向的容量保存到数据成员当中               
 m_pList = new int [m_iSize] ; //分配内存 
 m_iLength = 0 ;// 初始状态下 为0       //当前的线性表中究竟存放了几个线性表的元素         

List::~List()  // 析构函数  在析构函数中最主要的功能就是讲构造函数中申请的内存释放掉 
{
 delete []m_pList; 
 m_pList=NULL;
 
}

void List::ClearList(){
    // 实现清空的操作就是让ilength的值为0
    m_iLength=0; 
}

bool List::ListEmpty(){  // 判断线性表是否为空 
    if (m_iLength==0)
    {
        return true;
    }
    else{
        return false;
    }
    //return m_iLength==0?true:false;
}

int  List::ListLength()
{
    return m_iLength;
}


bool List::GetElem(int i,int *e)
{  //获取指定的元素 
    if(i<0||i>m_iSize)
    {//判断一下是否有这个元素  在这种情况下就没有办法取到指定的元素
     return false;
     }
     //  否则就把这个值传递给 e  
    *e=m_pList[i]; 
    return true;
}


int List::LocateElem(int *e)
{  // 寻找第一个满足e的数据元素的位序// 定位元素 也就是查找元素 需要用到for循环遍历的操作
     for(int i=0;i<m_iLength;i++)
     {
         if(m_pList[i]==*e)
         {
             return i;
         }
          
     } 
    return -1; // 没有找到 
}

bool List::PriorElem(int *currentElem,int *preElem)
{ //寻找前驱和后继 
     int temp=LocateElem(currentElem);  // 用一个返回值 存储找到的前驱的元素 
     if(temp==-1){  // 如果temp==-1  说明没有找到 
         return false; 
     } 
     else
     {
         if(temp==0){  // 则就在头位置 说明没有前驱 
             return false; 
         }
        else 
        { //既不等于零也不等于-1 则找到这个前驱 
            *preElem=m_pList[temp-1];  //将所找到的元素赋值给前驱 
            return true; 
        }
     }
}

void List::ListTraverse()
{
    for (int i=0;i<m_iLength;i++){  // i 小于当前表中的个数 
        cout<<m_pList[i]<<"  ";
    }    
}

bool List::NextElem(int *currentElem,int *nextElem){
    int temp=LocateElem(currentElem);  // 用一个返回值 存储找到的前驱的元素 
     if(temp==-1)
     {  // 如果temp==-1  说明没有找到 
         return false; 
     } 
     else
     {
         if(temp==m_iLength-1){  // 则就在尾位置 说明没有后继 
             return false; 
         }
        else { //既不等于零也不等于-1 则找到这个前驱 
            *nextElem=m_pList[temp+1];  //将所找到的元素作为后继元素 
            return true; 
        }
     }
}

bool List::ListInsert(int i,int *e){  //插入位置 后面的元素  需要依次往后移 
    // 需要增加一个判断条件
    if(i<0||i>m_iLength){
        return false;
    } 
    for(int k=m_iLength-1;k>=i;k--){  // k从最后一个元素操作不停的做k-- 一直到最后一个元素都往后移一个位置 
        m_pList[k+1]=m_pList[k];  // 先移动再插入 
    } 
    m_pList[i]=*e;
    m_iLength++;// 记录当插入到尾部 不进循环不需要移动位置 但是线性表的长度需要加一 ,并且记录当前线性表中已有的元素的个数 
    return true; 
}
bool List::ListDelete(int i,int *e){
    if(i<0||i>=m_iLength){  // 如果等于可以那么下面的删除不了任何元素 
        return false;    
    }
    *e=m_pList[i];// 将i位置上的元素先拷贝出来 
    for(int k=i+1;k<m_iLength;k++){  // 从当前的位置把后继的元素都往前移动 
        m_pList[k-1]=m_pList[k]; 
    }
    m_iLength--;
    return true;    
}

// 接下来我需要用的就是在main函数中调用我的方法和数据: 下面的文件我定义为 demo.cpp

#include<stdlib.h>
#include "List.cpp"
int main(void){
    int e1=3;
    int temp2; // 用于前驱元素存放 
    int temp3; // 用于后继元素的存放 
    int temp;// 定义临时变量 用它来去除删除掉的值 
    int temp1; // 用于查找元素 
    List *list1 = new List(10); // 调用构造函数传入一个容量 
//    list1->ListInsert(0,&e1); 
    
    for(int i=0;i<10;i++)
    {    int j;
        scanf("%d",&j);
        list1->ListInsert(i,&j); 
    }
    cout<<endl;
    cout<<"这是删除前的元素:"<<endl; 
    list1->ListTraverse();
    cout<<"没有删除元素之前线性表长度Length:"<<list1->ListLength()<<endl;
    list1->ListDelete(2,&temp);  // 删除指定的元素 记住这里面是指针 只需要知道删除的位置即可 
    cout<<endl<<"这是删除后的元素:"<<endl;
    list1->ListTraverse();
    cout <<endl<<"这是删除的位置的元素:"<<endl<<temp<<endl; 
//    if(!list1->ListEmpty())  // 在没有清空线性表时候 验证是否为空 
//    {
//        cout<<"not empty"<<endl; 
//     } 
//    list1->ClearList(); //清空线性表 
//    if(list1->ListEmpty())  // 清空之后验证了 
//    {
//        cout<<"empty"<<endl; 
//     } 
    cout<<"删除元素之后线性表长度Length:"<<list1->ListLength()<<endl; 
    cout<<list1->GetElem(4,&temp1)<<endl;
    cout<<temp1<<endl; 
    list1->LocateElem(&temp1); // 调用指定位置的函数 
    cout<<endl;
    list1->PriorElem(&temp1,&temp2);
    list1->NextElem(&temp1,&temp3); 
    cout<<"取到我指定删除的元素的前驱"<<temp2<<endl;
    cout<<"取到我指定删除的元素的后继"<<temp3<<endl; 
    delete list1;
    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值