在STL/MFC里的链表类强大支持下,回头看看曾经走过来的路...(原创)

这些天开始搞BREW,因为它没有STL/MFC的链表支持,所以不得不巩固一下以前所学的链表,有些感想,想与大家分享一下

#include "stdafx.h"
#include <iostream.h>
struct Student
{
 long  number;
 float  score;
 Student  *next;
};

Student *head; //链首指针

Student *Create()
{
 Student *pS; //创建的结点指针
 Student *pEnd; //链尾指针,用于在其后面插入结点

 pS = new Student; //新建一个结点,准备插入链表
 cin>>pS->number>>pS->score;
 head = NULL;
 pEnd = pS;   //让尾指针指向刚才生成的堆地址

 while(pS->number!=0)
 {
  if(head==NULL)
   head = pS;  //当head指向的地方为空,则把它做为首地址
  else
   pEnd->next = pS; //此处很重要,当两个相同类型的指针指向同一个地址,并且改变它们中任何一个成员值,另一个也随之改变,这就是间接引用

  pEnd = pS;   //当第二次循环时,需要把pEnd指向pS = new Student出来的新地址
  pS = new Student;
  cin>>pS->number>>pS->score;
 }
 pEnd->next = NULL;  //此处无效操作
 delete pS;   //因为循环最后一次,pS = new Student没有处理任何链表操作,所以要释放

 return (head);
}

void Delete(Student *head,long number)
{
 Student *p;
 if(!head)
 {
  cout<<"/nList null!/n"<<endl;
  return ;  //表示未作删除
 }

 if(head->number == number) //要删除的结点在链首,处理第一个结点
 {
  p = head;  //用p指向首地址
  head = head->next; //把head重新指向它自身的成员指针,也就是下一个结点地址
  delete p;  //释放由pS = new Student创建的内存
  cout<<number<<"the head of list have been deleted"<<endl;
  return;
 }
 //当第一个结点,没有搞定的情况下,继续遍例处理整个head,包括第一个
 for(Student *pGuard = head;  //同样,取首链结点地址
  pGuard->next;    //保证自身结点指向下一个的地址不为空
  pGuard = pGuard->next)  //把head重新指向它自身的成员指针,也就是下一个结点地址
 {
  if(pGuard->next->number == number) //在这里处理了除了第一个的余下的结点->next
  {
   p = pGuard->next; //找到指向此结点的地址,准备delete
   pGuard->next = p->next;//把后面的结点连上来
   delete p;   //删除指向这个堆的地址
   cout<<number<<"have been deleted"<<endl;
   return;
  }
 }
 cout<<number<<"not found!"<<endl;
}

void Insert(Student *head,Student *stud)
{
 if(head==NULL) //链表首地址为空,也就是把插入的结点放到此位置上
 {
  head = stud;//它将成为首链
  stud->next = NULL; //初始化它的下一个结点位置
  return;
 }
 if(head->number > stud->number)  //判断第一个结点值是否大于插入的结点值,是的话,结点插入的位置在链首
 {
  stud->next = head;  //把head挂在新插入结点后
  head = stud;   //让新插入结点成为首链
  return;
 }
 //否则,就需要逐个比较大小

 for(Student *pGuard = head;//取链首地址
  pGuard->next;   //保证自身结点指向下一个的地址不为空
  pGuard = pGuard->next) //把head重新指向它自身的成员指针,也就是下一个结点地址
 {
  if(pGuard->next->number >= stud->number)//当前结点的下一个结点值大于等于插入结点值
  {
   Student *p = pGuard;  //保存当前结点地址,因为下面需要把后面的挂在它的下面
   stud->next = pGuard->next; //让新插入的结点里的成员指向下一个结点地址
   p->next = stud;    //把新加入的结点挂在最后一个小于它的后面
   return;
  }
 }
}

void ShowList(Student *head)
{
 while(head)  //判断是不是指到头为空了
 {
  cout<<head->number<<":"<<head->score<<endl;
  head = head->next;//不断的指向保存下一个结点指针的自身成员的地址
 }
}

int main(int argc, char* argv[])
{
 Student ps;
 ps.number = 36;
 ps.score = (float)3.8;
 head = Create();
 Delete(head,2);
 Insert(head,&ps);
 ShowList(head);

 return 0;
}

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值