线性链表

#define true    1
#define false   0 
#define ok      1
#define error   0
#define infeasible  -1
#define overflow    -2

typedef int status;

//elemtype也可以定义为其它类型 
typedef struct{
    char name[20];
    int age;
}elemtype; 

//typedef线性链表类型 
typedef struct  LNode{
    elemtype elem;
    struct LNode *next; 
}LNode, *Linklist;

// 建一个线性链表的头结点
status Initlist( Linklist &l){
    l=(Linklist)malloc(sizeof(LNode));
    if(!l){
        printf("链表表头失败,无足够空间");
        exit(overflow);
    }
    l->next=NULL;
    return ok;
}


status listInsert(Linklist &l,int i,elemtype e){    //在线性链表中第i处插入一个元素e 
    int j=1;                            //j=1时,p=head。即j=1时指的是0号位的链表——表头。j=2时指的才是人类语言上1号位的链表。 
    Linklist p=l;
    while(p && j<i){                    //  令p为第i-1个结点
        p=p->next;                      //  初始      p=Head  j=1 i=3
        j++;                            //  1轮结束        p=1     j=2 i=3
    }                                   //  2轮结束        p=2     j=3 i=3 出循环,p恰好为前一个结点

    if(!p||j>i){                        //当除head所指链表仅有一个有elem的链表时,上面while依然第二轮结束,此时p为NULL,error:i值超过表长+1printf("您输入的i值不合法");    //当链表为空,仅有1个head,i=1,即插入1号位,while不执行,p不为NULL,j=i,插入正常进行。
        return error;               //当链表为空,仅有1个head,i=0,即插入0号位,while不执行,p不为NULL,但j>i,执行if程序。
    }       //p为i的前驱,!p表明只要p存在,则可以插入。i号位不一定要存在 
    Linklist s;
    Initlist(s);
    s->next=p->next;
    s->elem=e;
    p->next=s;
    return  ok;
}

status listDelete(Linklist &l,int i,elemtype e) {    //删除线性链表的第i处的结点,并将删除的值返回给e   
    int j=1; 
    Linklist p=l;
    while(p&&j<i){
        p=p->next;
        j++;
    }
    if(!p->next||j>i){                  //i小于1或者i大于表长。    
        printf("您输入的i值不合法");
        return error;           
    }       //p为i的前驱,!p->next表示必须存在,才能删除。i号位一定要存在。 
    Linklist q=p->next;
    p->next=q->next;
    e=p->elem; 
    free(q);
    return ok;
} 

status Getlist(Linklist l, int i, elemtype & e){    //取下标i的元素并赋给e
    int j=1; 
    while(l&&j<=i){
        l=l->next;
        j++;
    }
    if(!l||i<1){                    //注意,这里的i<1不能写成j>i,因为j一定是大于i的 
        printf("您输入的i值不合法");
        return error;           
    }
    e=l->elem; 
    return ok;
}

status listPrint(Linklist l){   //打印线性链表中所有元素
    if(!l) return error;
    while(l->next){     //注意:不是l,而是l->next,才能l=l->next,然后打印l。 
        l=l->next ;     //判断条件是l的话,最后一次判断时l->next==NULL,这时无法printf,error。 
        printf("%s\t%d\n", l->elem.name,l->elem.age);   
    }
    return ok;
}

status Clearlist(Linklist &l){  //重置一个线性链表
    Linklist p;
    if(!l) return error;
    while(l->next ){
        p=l->next;
        l->next=p->next;
        free(p);
    }
    return ok;
}

status  Destroylist(Linklist &l){   //释放一个线性链表
    Linklist p;
    if(!l) {
        return error;
    }
    while(l ){
        p=l;
        l=p->next;
        free(p);
    }
    return ok;
}

status listEmpty(Linklist l){   //检查线性链表是否为空。
    if(l->next)                 //空的意思是里面没有有效的元素。如果经摧毁后再判断是否为空则会出错,因为l->next这句执行不了。 
        return ok;
    else
        return error;
}

status listLength(Linklist l,int &n){ //测量线性表长度 
    n=0;
    if(!l) return error;
    while(l->next){
        l=l->next;
        n++;
    }
    return ok;
}

status Sortlist(Linklist &l){   //给线性链表排序。
    if(!l) return error;
    int is_exchanged=1;
    elemtype e;
    Linklist t,p;
    Initlist(t);
    Initlist(p);
    while(is_exchanged){
        p=l;
        is_exchanged=0;
        while(p->next->next){
            p=p->next;
            t=p->next;
            if(p->elem.age>t->elem.age){
                e=t->elem;
                t->elem=p->elem;
                p->elem=e;
                is_exchanged=1;
            }   
        }
    }
    return ok;
}

status Reverselist_recursion(Linklist l){   //用递归方法将线性表逆序输出,也可以用栈实现
    if(!l) return error;
    l=l->next;  //一开始想用Reverselist_recursion(l->next)并去掉这句。但是由于链表头的存在,会把链表头的未赋值的elem也打印出来。
    if(l->next){    //为了排除表头的特殊情况,只能开始就l->next,不让表头有机会printf。相应的,递归部分的l->next就改成了l。 
        Reverselist_recursion(l);    
    }
    printf("%s\t%d\n",l->elem.name,l->elem.age);
    return ok;
} 


status Reverselist_stack(Linklist l){   //将线性链表逆序排列,指针全部反过来 
    elemtype elems[100];
    int top=0; 
    l=l->next ;
    while(l){
        elems[top++]=l->elem;       
        l=l->next;
    }
    while(top>0){                           //如用printf("%s\t%d\n",elems[--top].name,elems[top].age),则会发生错位。原因如下: 
        printf("%s\t",elems[--top].name);   //  int sz[5]={0,1,2,3,4};
        printf("%d\n",elems[top].age);      //  int top=3;
    }                                       //  printf("%d\t%d\n",sz[--top],sz[top]);
}                                           //  //2       3

status Reverselist(Linklist &l){    //将线性链表逆序排列。链表原结构逆转。即链表转向 
    if(!l) return error;
    if(l->next&&!l->next->next) return ok;  //如果链表中仅有一个元素,正序和逆序一样,直接返回即可 
    Linklist p1,p2,num1,tmp;    //num1为原链表的结点1 
    num1=p1=l->next;
    p2=p1->next;
    while(p2){  //若条件为p2,则最后一个结点指向前一结点后,p1=p2;p2=tmp=NULL;tmp=tmp->next=NULL->next,则发生错误。 
        tmp=p2->next;
        p2->next=p1;
        p1=p2;
        p2=tmp;
    } 
    l->next=p1;
    num1->next =p2;  
    return ok; 
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值