链表学习例子

#include<iostream>
using namespace std;
#define node struct student
#define null 0
#define len sizeof(struct student)
struct student
{
    long num;
    float score;
    struct student *next;
};
int n;
struct student *creat()
{
    struct student *p1,*p2,*head;//声明好数据结构体之后,就要为它们创建数据链表的函数
    n=0;//用它来表示有几个这样的数据结构体
    p1=p2=(struct student*)malloc(len);//为初始的该数据结果类型变量,动态分配改好合适的内存空间
    cin>>p1->num>>p1->score;//内存中的空间以分配好,可以输入数据了
    head=null;//初始头指针应该是空的
    while(p1->num!=0)//与输入的某个数为零来停止不再输入
    {
       n=n+1;//一个整体的数已经建立就加一,它是全局变量
       if(n==1)head=p1;//是第一数就把作为头指针,指针之间可直接通过变量赋值,它们都是指针即表示地址
       else p2->next=p1;//前面都有节点,那么就加入前节点的后节点上
       p2=p1;//p2是作为中间节点的指针变量来交换的
       p1=(struct student*)malloc(len);//因为还要输入数据得在分配数据空间
       cin>>p1->num>>p1->score;
    }
p2->next=null;//最后的节点要记得指向空节点
return(head);
}  
struct student *del(struct student *head,long num)//删除数据的函数
{
     struct student *p1,*p2;
     node *pc;
     if(head==null)//考虑到健壮性或链表为空的情况处理
     {
        cout<<"list null!";
        goto end;
     }
     p1=head;//不是空链表,就把传进来的链表头指针交给中间指针变量
     while(num!=p1->num&&p1->next!=null)//判断是否存在要删除的数
     {
        p2=p1;//不是先暂时记录当前是节点
        p1=p1->next;//之后就是指向下一个节点
     }
     if(num==p1->num)//如果是要删除的数,则有如下的操作
     {
        if(p1==head)head=p1->next;//要是删除的数是头结点,那么得把头结点的下一个节点作为头结点
        else p2->next=p1->next;//不是头结点就把它的下一节点作为它上一节点的下一个数据节点
        n=n-1;//节点是数减一
        cout<<"delete data is:"<<num<<endl;
     }
     else cout<<"not been found!/t"<<num<<endl;
     end:
         return(head);//操作结束返回头节点
}
/*删除数据的函数是通过删除节点所实现的,首先要删除节点必须把链表的数据作为参数传
进来,同时要删除的数也作为参数传进来。首先判断待删除的数的链表是否为空,“0”或
“null”表示空,不为空是,判断要删除的数据是否一致,不一样,数据指向下一节点,找
到要删除的数时,用p2表示待删除节点的前一节点,再把待删除节点的下一节点地址赋给
p2节点的下一节点,为此达到了删除待删除节点的目的。*/       
void print(struct student *head)
{
     struct student *p;
     p=head;
     cout<<"These records are:"<<endl;
     while(p!=null)
     {
         cout<<p->num<<'/t'<<p->score<<'/n';
         p=p->next;
     }
}

struct student *insert(struct student *head,struct student *pn)//声明链表数据的头指针参数,及插入数据的节点指针参数
{
    node *pc,*pa;//声明两个结构节点指针变量,用于对插入数据的作为中间节点的转换
    pc=pa=head;  //首先初始化用于叫换的指针,把链表头指针赋与两指针。
    if(head==0) //如果链表是空的,有如下的操作
    {
       head=pn;  //将待插入的数据放入头指针
       pn->next=0; //同时下一个节点的指针要为空
       return head; //插入完数据,返回头节点指针
    }
    if(pn->score>=head->score)//如果插入的数据大于或等于头指针的数据,那么有如下操作
    {
      pn->next=head;  //待插入的节点设置为头节点的上节点,即直接把头节点指针赋给该插入节点下一个数据指针
      head=pn;     //而此刻待插入数据的节点指针正是头结点指针,所以直接把该节点指针赋给头结点即可
      return head;//插入操作完毕,返回头节点指针
    }
    while(pc->next!=0&&pn->score<=pc->score)//当待插入的节点数据小于或等于与头节点数据(或存在的数据),
    {    //并且头结点的下一个节点不是空的,有如下操作
       pa=pc;      //先把当前比较的节点数据指针赋给中间转换的指针变量pa
       pc=pc->next;//之后下一个节点作为当前要比较的节点,这里的下一个节点都是通过地址即指针来实现的
    }
    if(pn->score<=pc->score)//知道比较完所以链表中的数据,没有找到比要插入节点数据小时,则只能插入到最后
    {
       pc->next=pn;//把要插入的节点放到链表的最后一个节点的下一节点,作为新的最后一个节点
       pn->next=0;//同时不要忘了最后节点的下一节点要指向空,表示数据的结束
    }
    else
    { pn->next=pc;//除了比头结点的数据和上面比较的小于比较节点数据小之外,剩下的就是大与与它(插入的数)比较的数,如此就插入给数之前
      pa->next=pn;//该插入的节点作为之前还没插入节点时的前一节点的下一节点,因为链表的插入要表明前后节点之间的指向地址关系
    }
    return head;//最后插入操作完成之后当然是要返回链表的头结点了
}
   


int main()//在各函数模块都写好之后,编写主函数来对它们运用或测试也很重要,下面说明主函数如何编写调用它们
{
    struct student *head,*stu;//声明这两个数据指针,是由于后面的操作所需
    long del_num;//声明将要插入某数的变量
    cout<<"please input number's and score's data:"<<endl;//提示输入数据的操作
    head=creat();//建立数据链表,并把它的头指针的交给上面声明的头指针变量
    print(head);//直接用头指针变量作为参数调用输出函数
    cout<<"please input the delete number:"<<endl;//提示输入要删除的数据
    cin>>del_num;//输入要删除的数据
    while(del_num!=0)//输入零作为停止删除数据
    {
       head=del(head,del_num);//调用删除函数,完成操作新是数据头指针赋给声明的头指针变量
       print(head);//对取进行验证
       cout<<"please input the delete number:"<<endl;
       cin>>del_num;
    }
    cout<<"input the inserted record:"<<endl;
    stu=(struct student*)malloc(len);//因为要插入数据,所以得为插入的数据分配给一定的空间大小,此为类型、随机分配函数、大小的意思
    cin>>stu->num>>stu->score;//虽然已经给输入的数据分配好空间了,但是它还没和链表中是数据形成一条连,所以要要通过指针来连接起来
    while(stu->num!=0)//与输入的学好为零作为输入终止判断
    {
       head=insert(head,stu);//把此数据结构的节点传入到插入函数中,让其一链表连接在一起
       print(head);//输出函数验证之
       cout<<"input the inserted record:"<<endl;//以下语句决定是否还有插入数据
       stu=(struct student*)malloc(len);
       cin>>stu->num>>stu->score;
    }
    system("pause");
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值