• c++单链表基本功能


     

    head_LinkNode.h

    /*单链表类的头文件*/
    #include<assert.h>
    #include"compare.h"
    typedef int status;//整形的状态值
    #define OK 1;//status参数
    #define ERROR 0;//status参数
    template <class type>
    class LinkNode
    {
    protected:
    LinkNode* head;
    public:
    void out();//输出函数
    LinkNode()//对象初始化
    {
    data=0;
    next=NULL;
    head=NULL;
    }
    void menu();//菜单
    LinkNode<type> operator=(LinkNode<type> right);
    private:
    void sort();//排序
    void putin(int a);//输入函数
    status insert(int a,type b);//插入函数
    void clear();//清空
    void inversion();//倒置节点
    status delc(type a);//删除所有指定data节点
    status find(type a);//查找(通过参数号)
    status del(int a);//删除函数(指定位号)
    status locateELem(type e,status (*compare)(type,type));
    //成员变量
    type data;
    LinkNode<type> *next;
    static int n;//当前单链表元素个数
    //成员变量
    typedef LinkNode * nodepoint;//指向节点的指针(在类内不用给出类型 在对象生成时类型确定)
    };
    template <class type>
    int LinkNode<type>::n=0;//只能在类外初始化
    /*
    功能:运算符重载
    方法:先置空 左边 后通过滑动不断用右边赋值左边
    */
    template <class type>
    LinkNode<type> LinkNode<type>::operator=(LinkNode<type> right)
    {
    nodepoint p=NULL;//指向左边的单链表当前节点为空
    nodepoint rp=right.head;//指向右边的单链表当前节点
    nodepoint s;//在赋值过程中左边可能需要的新节点
    if(this!=&right)
    {
    clear();//清空左边
    while(rp)
    {
    s= new LinkNode;
    assert(s!=0);
    s->data=rp->data;
    if(!head)
    head=s;
    else
    p->next=s;
    p=s;
    rp=rp->next;
    }
    if(p)
    p->next=NULL;
    }
    return *this;
    }
    /*
    功能:在第a个节点前插入一个节点
    方法:先判断一种特殊情况(在头部插入) 并且特殊处理 对于普通情况采用先用循环滑动到指定节点前再做处理
    */
    template <class type>
    status LinkNode<type>::insert(int a,type b)
    {
    int j=1;//表示当前单链表的序号
    nodepoint p=head;//从第一个节点开始循环;
    nodepoint s;//用于插入
    if(a==1)//在头部插入情况
    {
    s= new LinkNode;
    assert(s!=0);
    (*s).data=b;
    (*s).next=head;
    head=s;
    n++;
    return OK;
    }
    if(a>n)
    return ERROR;
    while(p&&j<a-1)//从头节点开始滚动到指定插入点的前一个节点
    {
    p=p->next;
    j++;
    }
    s= new LinkNode;
    assert(s!=0);
    s->data=b;
    s->next=p->next;
    p->next=s;
    n++;
    char u='y';
    cout<<"是否排序?(y or n?)"<<endl;
    cin>>u;
    if(u=='y')
    sort();
    return OK;
    }
    /*
    功能:输入
    方法:通过插入和倒置函数实现
    */
    template <class type>
    void LinkNode<type>::putin(int a)
    {
    clear();
    type b;
    cout<<"输入开始"<<endl;
    for(;a>0;a--)
    {
    cin>>b;
    insert(1,b);
    }
    inversion();
    }
    /*
    功能:输出单链表
    方法:通过next指针不断滑动输出节点DATA
    */
    template <class type>
    void LinkNode<type>::out()
    {
    nodepoint p=head;
    cout<<"当前单链表"<<endl;
    while(p)
    {
    cout<<p->data<<' ';
    p=p->next;
    }
    cout<<endl;
    }
    /*
    功能:删除指定节点(指定位号)
    方法:滑动前驱节点和当前结点到指定位号 使前驱结点直接连接后继节点
    */
    template <class type>
    status LinkNode<type>::del(int a)
    {
    nodepoint p=head;//当前节点
    nodepoint r=NULL;//前驱节点
    int i=1;
    if(a>n)
    return ERROR;
    if(a==1)//特殊处理删除第一个节点
    {
    head=p->next;
    p=NULL;
    n--;
    return OK;
    }
    while(p&&i!=a)
    {
    r=p;
    p=(*p).next;
    i++;
    }
    if(a==n)//特殊处理删除尾节点
    {
    r->next=NULL;
    p=NULL;
    n--;
    return OK;
    }
    r->next=p->next;
    n--;
    p=NULL;
    return OK;
    }
    /*
    功能:返回查找的节点
    方法:滑动当前结点到指定位号 返回data
    */
    template <class type>
    status LinkNode<type>::find(type a)
    {
    nodepoint p=head;
    int i=1;
    while(p)
    {

    if(a==p->data)
    {
    cout<<a<<"是单链表中的第"<<i<<"个节点"<<endl;
    return OK;
    }
    i++;
    p=p->next;
    }
    return ERROR;
    }
    /*
    功能:清空单链表
    方法:以单链表节点数n为基准通过不断的调用del函数删除第一个节点从而清空单链表
    */
    template <class type>
    void LinkNode<type>::clear()
    {
    int i=1;
    while(head!=NULL&&i<=n)
    {
    del(1);
    i--;
    }
    n=0;
    }
    /*
    功能:倒置单链表
    方法:先把next指针从链向后变为链向前 然后通过变换前驱、当前、后继的指向重复变换next 及完成倒置
    */
    template <class type>
    void LinkNode<type>::inversion()
    {
    if(n==0)
    return;
    nodepoint p=head;
    nodepoint r=NULL;
    nodepoint q=p->next;
    while(p)
    {
    p->next=r;
    r=p;
    p=q;
    if(q)//保证后继指针q不会出表
    q=p->next;
    }
    head=r;
    }
    /*
    功能:删除所有指定data节点
    方法:从头滚动到链尾找到与参数a相等的data就利用del函数删除这个节点
    */
    template <class type>
    status LinkNode<type>::delc(type a)
    {
    nodepoint p=head;
    int i=1;
    int c=ERROR;
    while(i<=n)
    {
    if(p->data==a)
    {
    del(i);
    i=i-1;//删除后从上一位开始找
    c=OK;
    }
    p=p->next;
    i++;
    }
    return c;
    }
    /*菜单*/
    template <class type>
    void LinkNode<type>::menu()
    {
    char p='y';
    int a;
    for(;;)
    {
    cout<<"****************************处理菜单****************************"<<endl;
    cout<<"1.输入"<<endl;
    cout<<"2.输出"<<endl;
    cout<<"3.插入"<<endl;
    cout<<"4.倒置"<<endl;
    cout<<"5.查找"<<endl;
    cout<<"6.删除指定位号节点"<<endl;
    cout<<"7.删除指定元素在单链表中的所有节点"<<endl;
    cout<<"8.清空单链表"<<endl;
    cout<<"9.排序"<<endl;
    out();
    cout<<"****************************处理菜单****************************"<<endl;
    cout<<"请选择:";
    cin>>a;
    switch(a)
    {
    case 1:{
    int b;
    cout<<"请输入你要输入节点的个数"<<endl;
    cin>>b;
    putin(b);
    };break;
    case 2:{
    out();
    };break;
    case 3:{
    type c;
    int y;
    cout<<"请输入你要插在那位节点前面"<<endl;
    cin>>y;
    cout<<"请输入你要插入的元素"<<endl;
    cin>>c;
    if(insert(y,c))
    cout<<"OK"<<endl;
    else
    cout<<"ERROR";
    };break;
    case 4:{
    inversion();
    };break;
    case 5:{
    type y;
    cout<<"请输入你要查找的数据"<<endl;
    cin>>y;
    if(find(y))
    cout<<"OK"<<endl;
    else
    cout<<"ERROR"<<endl;
    };break;
    case 6:{
    int y;
    cout<<"请输入你要删除的节点位号"<<endl;
    cin>>y;
    if(del(y))
    cout<<"OK"<<endl;
    else
    cout<<"ERROR";
    };break;
    case 7:{
    type y;
    cout<<"请输入你要删除的元素"<<endl;
    cin>>y;
    if(delc(y))
    cout<<"OK"<<endl;
    else
    cout<<"ERROR";
    };break;
    case 8:{
    clear();
    };break;
    case 9:{
    sort();
    };break;
    }
    getchar();//接受回车
    cout<<"是否继续处理?(n退出)"<<endl;
    p=getchar();
    system("cls");
    if(p=='n')
    break;
    }
    }
    /* 功能:排序
    方法:使用冒泡排序通过不断滚动对比data交换data达到排序目的
    */
    template <class type>
    void LinkNode<type>::sort()
    {
    nodepoint p=head;
    nodepoint q=p->next;
    type s;
    for(int i=0;i<n;i++)
    {
    p=head;
    q=p->next;
    for(int c=0;c<n-i-1;c++)
    {
    if(p->data>q->data)
    {
    s=p->data;
    p->data=q->data;
    q->data=s;
    }
    p=p->next;
    q=p->next;
    }
    }
    }
                                                                                                      LinkNode.cpp

    #include"head_LinkNode.h"
    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
    int a;
    char p='y';
    for(;;)
    {
    cout<<"请输入你要处理的数据类型(char(1) int(2) float(3) double(4) )"<<endl;
    cin>>a;
    switch(a)
    {
    case 1: {LinkNode<char> sq;
    sq.menu();
    }break;
    case 2: {LinkNode<int> sq;
    sq.menu();
    }break;
    case 3: {LinkNode<float> sq;
    sq.menu();
    }break;
    case 4: {LinkNode<double> sq;
    sq.menu();
    }break;
    default: cout<<"错误请重新输入"<<endl;
    }
    cout<<"是否继续处理其他类型顺序表? 请输入 任意字符继续或n结束"<<endl;
    getchar();
    p=getchar();
    if(p=='n')
    break;
    }
    system("pause");
    }

  • 相关阅读:
    atitit.http get post的原理以及框架实现java php
    atitit.php中的dwr 设计模式
    Atitit.jquery 版本新特性attilax总结
    atitit.LimeSurvey 安装 attilax 总结
    atitit.php 流行框架 前三甲为:Laravel、Phalcon、Symfony2 attilax 总结
    atitit.项目设计模式---ioc attilax总结
    atitit.nfc 身份证 银行卡 芯片卡 解决方案 attilax总结
    atitit.提升研发效率的利器---重型框架与类库的区别与设计原则
    atitit。企业组织与软件工程的策略 战略 趋势 原则 attilax 大总结
    atitit.企业管理----商业间谍策略的使用与防务
  • 原文地址:https://www.cnblogs.com/cyh1282656849/p/5499515.html
Copyright © 2020-2023  润新知