IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 数据结构_链表表_基本操作的c++实现 -> 正文阅读

[C++知识库]数据结构_链表表_基本操作的c++实现

#include <iostream>

using namespace std;

//链表
//基本操作

//定义单链表
typedef struct LNode{
    int data;//数据域
    struct LNode *next;//指针域,指向下一个节点
}LNode,*LinkList;
/*---------------------------等价于------------------------------
struct LNode{
    int data;
    struct LNode *next;
};
typedef struct LNode LNode;
typedef struct LNode *LinkList;
-------------------------------------------------------------*/

//初始化单链表(不带头节点)
bool InitList_1(LinkList &L){
    L=NULL;                    //空表,暂时还没有任何节点
    return true;
}
//判空(不带头节点)
bool Empty_1(LinkList L){
        return (L==NULL);
}

//初始化单链表(带头节点)   //带头结点写代码比较方便
bool InitList(LinkList &L){
    L=(LNode *)malloc(sizeof(LNode));
    if(L==NULL)                  //内存不足,分配失败
        return false;
    L->next = NULL;           //头结点之后暂时还没有结点
    return true;
}
//判空(带头结点)
bool Empty(LinkList L){
    if(L->next==NULL)
        return true;
    else
        return false;
}

//插入:
//按位序插入,在第i个位置插入元素e(不带头结点)
bool ListInsert_1(LinkList &L,int i,int e){
    if(i<1)
        return false;
    LNode *s=(LNode *)malloc(sizeof(LNode));
    s->data=e;
    if(i==1){
        s->next=L;
        L=s;
        return true;
    }
    LNode *p=L;
    for(int j=1;p!=NULL&&j<i-1;j++) //循环找到第i-1个结点,因没有头结点,故结点数从1开始,j=1而非0,j代表p指向的结点为第几个(序号)
        p=p->next;
    if(p==NULL)                  //i值不合法,
        return false;
    s->next=p->next;
    p->next=s;
    return true;
}

//指定结点的后插操作
bool InsertNextNode(LNode *p,int e){
    if(p==NULL)          //给定结点不存在
        return false;
    LNode *s=(LNode *)malloc(sizeof(LNode));
    if(s==NULL)
        return false;//内存分配失败
    s->data=e;
    s->next=p->next;
    p->next=s;
    return true;
}

//按位序插入,在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList &L,int i,int e){
    if(i<1)
        return false;
    LNode *p; //指针p指向当前扫描到的结点
    int j=0;
    p=L;//L指向头节点,头节点是第0个节点(不存数据)
    while(p!=NULL&&j<i-1){//循环找到第i-1个结点
        p=p->next;
        j++;
    }
    InsertNextNode(p,e);
    /*
    if(p==NULL)  //i值不合法
        return false;
    LNode *s=(LNode *)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;//!顺序不
    p->next=s;    //!能颠倒
    */
    return true;
}

//指定结点的前插操作
bool InsertPriorNode(LNode *p,int e){
    if(p==NULL)
        return false;//给定结点不存在
    LNode *s=(LNode *)malloc(sizeof(LNode));
    if(s==NULL)
        return false;//内存分配失败
    s->data=p->data;
    s->next=p->next;
    p->next=s;
    p->data=e;//偷天换日,嘻嘻!
    return true;
}

//删除启动!
//按位序删除,删除表中第i个位置的元素,并用e返回删除元素的值(带头结点)           时间复杂度为O(n)
bool ListDelete(LinkList &L,int i,int &e){
    //if(L==NULL)
      //  return false;//L为空表
    if(i<1)
        return false;//i值不合法
    LNode *p=L;
    for(int j=0;p!=NULL&&j<i-1;j++)//找到第i-1个结点
        p=p->next;
    if(p==NULL)
        return false;//i值不合法,在i之前的结点p已经为空,该判断语句包含了表L为空表这一情况
    LNode *q=p->next;    //必须还要一个指向第i个结点的指针才行
    p->next=q->next;
    e=q->data;
    free(q);
    return true;
}

//删除指定结点p
bool DeleteNode(LNode *p){
    if(p==NULL)
        return false;//指定结点不存在
    LNode *q=p->next;  //时间复杂度为0(n),我狂偷!!!,,,,,但是如果p->next==NULL,就不行了,只能从第一个结点开始遍历,时间复杂度为O(n)
    p->next=q->next;
    p->data=q->data;
    free(q);
    return true;
}

//查找
//按位查找,返回第i个元素(带头结点)
LNode *GetElem(LinkList L,int i){


    if(i<1)
        return NULL;
    LNode *p=L;//指针p指向当前扫描到的结点,L指向头结点,头结点是第0个结点(不存数据)
    int j=0;   //当前p指向的是第几个结点
    while(p!=NULL&&j<i){  //循环找到第i个结点
        p=p->next;
        j++;
    }
    return p;
}

/*-----------和上面的GetElem函数等效
LNode *GetElem(LinkList L,int i){
    int j=1;
    LNode *p=L->next;
    if(i==0)
        return L;            //显示出该链表 带头结点
    if(i<1)
        return NULL;
    while(p!=NULL&&j<i){
        p=p->next;
        j++;
    }
    return p;
}
*/

//按值查找,找到数据域==e的结点
LNode *LocateElem(LinkList L,int e){
    LNode *p=L->next;
    while(p!=NULL&&p->data!=e)
        p=p->next;
    return p;//找到后返回该结点指针,否则返回NULL
}

//求表的长度(带头结点)
int Length(LinkList L){
    LNode *p=L->next;
    int len=0;
    while(p!=NULL){
        p=p->next;
        len++;
    }
    return len;
}

//尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
    int x;
    L=(LinkList)malloc(sizeof(LNode));//建立头结点
    LNode *s,*r=L; //r为表尾指针
    scanf("%d",&x);
    while(x!=9999){  //输入9999表示结束,自定义的
        s=(LNode *)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;             //指向新的表尾结点
        scanf("%d",&x);
    }
    r->next=NULL;    //尾结点指针置空
    return L;
}

//头插法建立单链表    !!!!!重要应用:链表的逆置
LinkList List_HeadInsert(LinkList &L){
    int x;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    LNode *s;
    scanf("%d",&x);
    while(x!=9999){
        s=(LNode *)malloc(sizeof(LNode));
        s->data=x;
        s->next=L->next;
        L->next=s;
        scanf("%d",&x);
    }
    return L;
}

//头插法建立单链表(不带头结点)
LinkList List_HeadInsert_1(LinkList &L){
    int x;
    LNode *s;
    L=NULL;
    scanf("%d",&x);
    while(x!=9999){
        s=(LNode *)malloc(sizeof(LNode));
        s->data=x;
        s->next=L;
        L=s;
        scanf("%d",&x);
    }
    return L;
}

/*-----------------------------双链表-------------------------------*/
//双链表不可随机存取,按位查找、按值查找操作都只能用遍历的方式实现。时间复杂度O(n)
//定义
typedef struct DNode{   //double
    int data;
    struct DNode *prior,*next;   //前驱和后继
}DNode,*DLinkList;

//初始化双链表(带头结点)
bool InitDLinkList(DLinkList &L){
    L=(DNode *)malloc(sizeof(DNode));
    if(L==NULL)
        return false;
    L->prior=NULL;
    L->next=NULL;
    return true;
}

//双链表的插入(在p结点之后插入s结点)
bool InsertNextDNode(DNode *p,DNode *s){
    if(p==NULL||s==NULL)
        return false;
    s->next=p->next;
    s->prior=p;
    if(p->next!=NULL){  //如果p结点有后继结点
        p->next->prior=s;
    }
    p->next=s;   //这一步一定在最后
    return true;
}

//双链表的删除(删除p结点的后继结点q)
bool DeleteNextDNode(DNode *p){
    DNode *q=p->next;
    if(p==NULL||q==NULL)
        return false;
    p->next=q->next;
    if(q->next!=NULL)
        q->next->prior=p;
    free(q);
    return true;
}

//销毁双链表
void DestoryDList(DLinkList &L){
    //循环释放各个数据结点
    while(L->next!=NULL)
        DeleteNextDNode(L);
    free(L); //释放头结点
    L=NULL;  //头指针指向NULL
}

//双链表的遍历
void Travel(DNode *p){
    //后向遍历
    while(p!=NULL)
        p=p->next;
    //前向遍历
    while(p!=NULL)
        p=p->prior;
    //跳过头结点的前向遍历
    while(p->prior!=NULL)
        p=p->prior;
}

/*----------------------循环单链表----------------------------------------------*/
//表尾指针的next指向头结点
//从表尾找到表头时间复杂度仅为O(1),故可以让L指向表尾元素(插入、删除时可能需要修改L)
//定义同单链表相同

//初始化
bool InitCycleList(LinkList &L){
    L=(LNode *)malloc(sizeof(LNode));
    if(L==NULL)
        return false;
    L->next=L;       //!
    return true;
}

//判断循环单链表是否为空
bool CycleEmpty(LinkList L){
        return (L->next==L);
}

//判断结点p是否为循环单链表的表尾结点
bool CycleisTail(LinkList L,LNode *p){
    return (p->next==L);
}

/*----------------------循环双链表----------------------------------------------*/
//表头结点的prior指向表尾结点
//表尾结点的next指向表头结点

//初始化
bool InitCycleDLinkList(DLinkList &L){
    L=(DNode *)malloc(sizeof(DNode));
    if(L==NULL)
        return false;
    L->prior=L;
    L->next=L;
    return true;
}

//循环双链表的判空
bool CycleDEmpty(DLinkList L){
    return (L->prior==L&&L->next==L);
}

//判断结点p是否为循环双链表的表尾结点
bool CycleDisTail(LinkList L,LNode *p){
    return (p->next==L);
}

/*---------------------------------静态链表-----------------------*/
//用数组的方式实现的链表
//定义
#define MaxSize 10
typedef struct{
    int data;
    int next;
}SLinkList[MaxSize];//调用时 SLinkList a;等价于 struct Node a[MaxSize];

//初始化
bool InitSLinkList(SLinkList &a){
    a[0].next=-1;
    return true;
}

//查找:从头结点出发挨个儿往后遍历结点

//插入位序为i的结点:
//1.找到一个空的结点,存入数据元素
//2.从头结点出发找到位序为i-1的结点
//3.修改新结点的next
//4.修改i-1号结点的next

//删除某个结点:
//1.从头结点出发找到前驱结点
//修改前驱结点的游标
//被删除结点next设为-2(-2代表该结点已被回收,里面已经没有数据了)

int main()
{
    int *a;
    int c=20;
    a=&c;
    int *b=a;


    cout << b << endl;
    cout <<a << endl;
    cout << *a << endl;
    cout << *b << endl;
    return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 11:52:27  更:2021-08-19 11:53:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 5:01:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计