test

来源:互联网 发布:数控铣床编程格式 编辑:程序博客网 时间:2024/06/09 23:45

//链表应用1

#include <iostream.h>
#include <malloc.h>
#include <stdio.h>
typedef int elemtype;
//定义结构体

typedef struct node
{
 elemtype data; //数据域

 struct node *next; //指针域

}linklist,*prtnode;

/*
(1)create linklist
表与顺序表不同,它是一种动态管理的存储结构,链表中的每个结点占用的存储空间不是预先分配
,而是运行时系统根据需求而生成的,因此建立单链表从空表开始,每读入一个数据元素则申请一
个结点,然后插在链表的尾部。
*/

//算法描述跟随输入

linklist *createlist(int n)
{
 int i; 
 int x; 
 /*
 初始化操作,定义phead(头指针,给他分配空间),定义尾指针ptail,定义跟随指针pfollow;
 linklist *phead ,*ptail,*pfollow;
 phead = new linklist; 
 ptail = phead;
 pfollow = phead;
 ptail->next = NULL; // 一定要加空表
 */

 //构建头结点空间 

  linklist *phead; 
 phead = new linklist; 
    //构建尾结点,不断读入数->next=NULL;

 linklist *ptail;
 ptail = phead; 
 ptail->next = NULL;//创建空表p->phead==NULL,应用程序不出错

    
 
    //构造跟随指针

    linklist *pfollow;
 pfollow = phead;
 
 //循环构建n个结点 

 for(i = 1; i<=n; i++)
 {
  cout<<"第"<<i<<"个";
  cin>>x;
  //不断取得空间,完成一个结点工作ptail

  ptail = new linklist; //h,f,t本身地址0x003708a8;next:0x00000000; data:NULL 

  ptail->data = x; //h,f本身地址0x003708a8;next:0x00000000; data:NULL /t本身0x00370d80 next:0xcdcdcdcd data:NULL

  ptail->next = NULL; //h,f本身地址00x003708a8;next:0x00000000; data:NULL /t本身0x00370d80 next:0xcdcdcdcd data:5

     //由于起初fh相互关联,告诉他们下个地址就是ptail

  pfollow->next = ptail; //h,f本身地址0x003708a8;next:0x00000000; data:NULL /t本身0x00370d80 next:0x00000000 data:5

  //一个结点本身地址和next地址,将next地址传给本身,meaning将本身跳到该结点

  pfollow = pfollow->next ; //*h,f本身0x003708a8,next:0x00370d80,data:null /t本身0x00370d80 next:0x00000000 data:5

 } //h本身0x003708a8,next:0x00370d80,data:null /f,t 本身0x00370d80 next:0x00000000 data:5

                                     
 return phead;
}
//倒置输入//先读数据,将数据插入

linklist *createlist2(int n)
{
  
 int i;
 linklist *p;
    linklist *phead;
 phead = new linklist;//头结点空间

 phead->next=NULL;
 for(i=1;i<=n;i++)
 {
  //初始化新结点

  p=new linklist;
  cout<<"第"<<i<<"个";
  cin>>p->data;
  //插入

  p->next=phead->next; 
  phead->next=p;
 }
 linklist *end;
 end=phead;
   
/// if(end->next==NULL)

// {

//

// phead=phead->next;

// }

  
// while(end->next!=NULL)

// {

// end=end->next;

// }

// end->next=phead;

 return phead;
 
}

/*
(2)查找<一>
查找元素按值查找:(从头指针开始)
在链表中查找是否有结点等于给定值key的结点
若有则返回首次找到值的存储位置,否则返回null
算法思想:
从开始结点出发,顺链表逐个结点的值和给定key做比较
*/

linklist *locate(const linklist *phead,elemtype &e) //phead是头结点,不是首结点

                                               //or prtnode locate(prtnode phead,elemtype &e)

{
 linklist *pindex; 
 pindex = phead->next; //从头结点获得首结点 

 while(pindex!=NULL) //while(pindex!=NULL&&pindex->data!=x)

 { //{ pindex = pindex->next; }

  if(pindex->data==e) 
  {
   cout<<"找到了";
      break; 
  }
  pindex = pindex->next; 
 } 
 
 //跳出循环访问到pindex为

/*
和head没关系 
while里不能用做pindex->pnext!=NULL,错误很多:
如因为若为空表,首结点data没有值,pindex->data访问出错
如果第二个结点(不包括头结点),为空,while(pindex->pnext!=null)
为真,没法对首结点进行访问;只能是while(pindex!=NULL)形式
*/

return pindex;
}
/*<二>
查找元素按序号查找(从头指针开始)
设单链表长度为length,要查找第i个结点
算法思想
从头结点开始扫描.用j做已扫描的计数器,当p扫描下一个结点时,j++;
p的初值指向头结点,j=0
当j==i,,指针p所指就是第i个结点
*/

linklist *findi(linklist *phead,elemtype i_base)
{
 int j_add;
 linklist *pindex;
 pindex = phead->next;
 j_add = 1;
 while(pindex!=NULL) 
 { //while(p && j<i ) 

  if(i_base==j_add) 
  {
   
          //{

   break; 
  } // j++;p = p->next;

  pindex = pindex->next; //}

  j_add++;
 }
 return pindex;
}
/*
(3)插入元素<定值后插一>
类似于查找运算,单链表的插入运算也可分两种方式来处理,一种按给定值插入
另一种按给定序号插入,根据给定的问题而定。下面主要讨论按给定值来处理。
*/

linklist *insertlist( linklist *phead,elemtype compare,elemtype insert)
{
 linklist *ptem;
 linklist *pinsert;
 //初始化一个结点,赋值

 pinsert = new linklist;
 pinsert->data = insert;
 pinsert->next = NULL;
 ptem = phead->next;
 if(NULL==ptem) //空表直接插入

 {
  phead->next = pinsert;
 }
    else
 {
  while( ptem->next!=NULL && ptem->data!=compare ) //条件要注意 ptem && ptem->next 能保证链表有两个元素

   ptem=ptem->next; //两种推出情况end退出,找到推出

  if(ptem->data==compare) //在此访问会出问题,处理找到推出

  {
   pinsert->next = ptem->next; //注意交换次序

   ptem->next = pinsert;
  }
  else //处理end推出

  {
   ptem->next=pinsert;
  }
 }
    return phead;
}
//插入按值<前插二>

linklist *insertlist2(linklist *phead,elemtype compare,elemtype insert)
{
 linklist *ptem;
 linklist *ptemnext;
                                 //初始化一个结点,赋值

 linklist *pinsert;
 pinsert = new linklist;
 pinsert->data = insert;
 pinsert->next = NULL;
    
    ptem=phead->next; //链表为空时做前插

 if(NULL==ptem)
 {
   phead->next = pinsert;
 }
 else
 {
   while( ptem && ptem->next) //限制存在两个结点,//ptemnext,和ptem

  { 
   ptemnext=ptem->next;
   if(ptem->data==compare) //当compare首次出现在ptem时做前插

   {
    phead->next=pinsert; 
    pinsert->next=ptem;
    break;
   }
    
   if(ptemnext->data==compare) //根据ptemnext比较做前插

   {
     ptem->next=pinsert;
    pinsert->next=ptemnext;
    break;
   }
   ptem=ptem->next; //下一个,指针后移

   ptemnext=ptemnext->next;
  }
  //限制一个结点,做前插

  if(ptem->data==compare &&ptem->next==NULL)
  {
   phead->next=pinsert;
   pinsert->next=ptem;
  }
  else //都没有匹配时做最后一个插入

  {
   ptem->next=pinsert;
   pinsert->next=ptemnext;
  }
 }
  return phead;
}
/*
单链表删除
*/

//按值删除

linklist *dellist(linklist *phead,elemtype delelem)
{
 linklist *ptem;
 linklist *ptemnext;
 ptem=phead->next;
 if(ptem==NULL)
 {
  cout<<"the link is empty/n";
  return phead;
 }
  
  
 while(ptem!=NULL && ptem->next!=NULL) //限制两个结点

 {
  ptemnext=ptem->next;
  if(ptemnext->data==delelem)
  {
   ptem->next=ptemnext->next;
  }
  ptem=ptem->next;


 }
 return phead;
}
//按序号删除

linklist *dellist2(linklist *phead,int i)
{
 linklist *pfollow;
 linklist *ptem;
 int j; //j++确定删除的元素次序

 pfollow=phead->next; 
 if(i==1) //限制结点为首结点

 {
  phead->next=pfollow->next;
  //phead=pfollow ; 

 }
 else //其余结点

 {
  j=1;
  while( pfollow!=NULL && j<i-1) //follow保证不超过链表尾地址

  {
     pfollow = pfollow->next;
   j++;
  }
 
  ptem=pfollow->next; //删除元素

  pfollow->next=ptem->next;
  delete ptem; //不要忘记释放指针

 }
 return phead;

}
//()输出数据

int printlist(const linklist *phead)
{
  
 linklist *ptemp;
 ptemp = phead->next;
 while(ptemp) //while(ptemp!=NULL) 更安全

 { 
  cout<<ptemp->data<<" "; 
  ptemp = ptemp->next;
 }
 cout<<endl;
 return 1;
}
linklist *empty(linklist *phead)
{
 linklist *ptem;
 linklist *ptem_release;
 ptem = phead->next;
 if(ptem==NULL)
 {
  return phead;
 }
 while(ptem)
 {
  ptem_release=ptem;
  ptem=ptem->next;
  delete ptem_release;
 }
 delete ptem;
 phead->next=NULL;
 return phead;
}
int lengthlist(const linklist *phead)
{
 int length=0;
 linklist *ptem;
 ptem=phead->next;
 while(ptem)
 {
  ptem=ptem->next;
  length++;
 }
 return length;
}
void destorylist(linklist *phead)
{
 linklist *ptem;
 linklist *ptem_release;
 ptem = phead->next;
 //删除非头结点,释放内存

   while(ptem)
 {
  ptem_release=ptem;
  ptem=ptem->next;
  delete ptem_release;
 }
  //释放头结点

  delete phead;
 

}
/*
linklist *createlist(int n);
linklist *createlist2(int n);
linklist *locate(const linklist *phead,elemtype &e);
linklist *findi(linklist *phead,elemtype i_base);
linklist *insertlist( linklist *phead,elemtype compare,elemtype insert);
linklist *insertlist2(linklist *phead,elemtype compare,elemtype insert);
linklist *dellist(linklist *phead,elemtype delelem);
linklist *dellist2(linklist *phead,int i);
void printlist(const linklist *phead);
linklist *empty(linklist *phead)
int lengthlist(const linklist *phead)
*/

void information()
{
 printf(" ----------------------------------------/n");
 printf(" | Test 链表应用测 |/n");
 printf(" |__ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|/n");
 printf(" | 1. 初始化化链表 |/n");
 printf(" | 2. 查询数据是否在表中 |/n");
 printf(" | 3. 查询表中数据的号码 |/n");
 printf(" | 4. 前插数据 |/n");
 printf(" | 5. 后插数据 |/n");
 printf(" | 6. 删除指定位置数据 |/n");
 printf(" | 7. 删除所选数据 |/n");

 printf(" | 8. 打印链表数据 |/n");
 printf(" | 9. 将已有链表置空 |/n");
 printf(" | 10. 返回表中的数据个数 |/n");
          
 printf(" | 0. 退出程序 |/n");
 printf(" --------------------------------------- /n");
 printf(" /n/n");
 printf(" <按99重新打印帮助说明>/n");
}
int mainwhile(void)
{
 linklist test;
 linklist *head;
 int n=0;
 int length=0;
 int compare;
 int insert;
 int del;
 int finde;
 int base;
 int i_base;
 information();
 cout<<"请输入您选择的号码___";
 cin>>base;
 
 while(1)
 {
  
  switch (base)
  {
   case 1:
    cout<<"请输入数据总数____";
    cin>>n;
    head=createlist(n);
    break;
   case 2: 
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    cout<<"请输入要查询的数据__";
    cin>>finde;
    head=locate(head,finde);
    break;
   case 3: 
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    cout<<"请输入要查询的序列___";
    cin>>i_base;
    head=findi(head,i_base);
    break;
   case 4:
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    cout<<"请输入要插入的数据__";
    cin>>insert;
    cout<<"请选定在哪个数据前插入__";
    cin>>compare;
    head=insertlist2(head, compare, insert);
    break;
   case 5:
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    cout<<"请输入要插入的数据__";
    cin>>insert;
    cout<<"请选定在哪个数据后插入__";
    cin>>compare;
    head=insertlist(head, compare, insert);
    break;
   case 6:
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    cout<<"请输入要删除数据的位置__";
    cin>>i_base;
    head=dellist2(head, i_base);
    break;
   case 7:
    if(n==0)
    {
    cout<<"请先初始化表";
    break;
    }
    cout<<"请输入要删除的数据";
    cin>>del;
    head=dellist2(head,del);
    break;
    case 8:
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    cout<<"表的内容为/n";
    printlist(head);
    break;
   case 9:
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    n=0;
    empty(head);
       printlist(head);
       information();
    break;
   case 10:
    if(n==0)
    {
     cout<<"请先初始化表";
     break;
    }
    length=lengthlist(head);
    cout<<"表中的数据个数为:/n";
    cout<<length;
    break;
   case 99:
    cout<<"/n/n/n/n/n";
    information();
    break;
   case 0:
    cout<<"感谢使用/n";
    return 0;

    
  }
  cout<<"/n请输入您选择的号码___";
  cin>>base;
 }
 return 1;
}
void main()
{
 
  mainwhile();
  
}