数据结构与算法(单向链表)

/*
    Name: 线性单向链表的操作 
    Copyright: 
    Author:abit
    Date: 07/01/17 15:41
    Description: 创建,打印,删除,添加,排序 ,查询 
*/
#include <stdio.h>
#include <stdlib.h>
#define N 10
#define ERROR 0 
struct Node{
    int data;//数据区域
    struct Node *next;//指针区域的指针也是结构体类型的 
};

struct Node *creatlist()
{
    struct Node *head,*p,*q;
    int i=0; 
    head=p=q=(struct Node *)malloc(sizeof(struct Node));//这里遵循指针先赋值再使用的法则 
    //这里的指针指向的是head->next这个指针 
    for(p=head->next;i<N;p=p->next,++i){
        //开辟p的结构体内存 并且给p定义一个值  
        p=(struct Node *)malloc(sizeof(struct Node));//先赋值p 
        p->data=rand()%100;//赋值 
        p->next=NULL;//为了最后一个是空指针 
        q->next=p;// 我们可以看到原本head一样的q的->next指针被指向了p 
        q=p;
    }
    return head;
}

struct Node *display(struct Node *head)
{
    struct Node *p;
    int i=0;
    for(p=head->next;p!=NULL;++i,p=p->next){
        printf("%d\t",p->data);
        if((i+1)%5==0)  printf("\n");
    }
}

int GetLenOfNode(struct Node *head)
{
    struct Node *p;
    int len=0;
    for(p=head->next;p!=NULL;p=p->next) len++;
    return len;
}
struct Node *maxvalue(struct Node *head)
{
    struct Node *p,*max;//这里的 p=head->next,max=head->next指向的是空白的head的指针指向的结构体
    for(p=head->next,max=head->next;p!=NULL;p=p->next){ 
        if(max->data<p->data)   max=p;//替换max的地址 
    }
    return max;
}

struct Node *sortlist(struct Node *head)
{
    struct Node *h=(struct Node *)malloc(sizeof(struct Node));//h为新的排序过后的链头 
    struct Node *p,*max; //指向结构体指针域的指针 
    struct Node *pbef,*maxbef;//这里为了让pbef和maxbef在max和p前面所以在下面的赋值直接赋值的head这个结构体 
    struct Node *rear;//这个是新的结构体的新元素 
    h->next=NULL;  
    rear=h;//将rear被h赋值 

    while(head->next!=NULL)//因为后面的指针会被一个一个改变所以判断是否为空 
    {
    //这里的pbef和maxbef指向head,因为是在p,max,之前的指针 
        for(p=head->next,max=head->next,pbef=head,maxbef=head;p!=NULL;p=p->next,pbef=pbef->next)
        //每次第二重循环就是判断p->next的空情况 
        {
            if(max->data<p->data){
                max=p;
                //这里的 maxbef被pdef赋值 
                maxbef=pbef;
            }
        } 
        maxbef->next=max->next;//将最大的结构体里的元素所在的 max->next赋值给了前面的 
        max->next=rear->next;//这里是将rear->next赋值给了max->next 
        rear->next=max; 
        rear=max;//将max的最大元素和rear->next元素赋值给了rear所以 
    }
    free(head);
    return h;
}

struct Node *addnum(struct Node *head,int AddOfNumber,int address)
{
    int j=1;
    struct Node *p,*s;
    p=head;
    if(address>N){
        printf("输入的插入位置超出长度\n");
        return head;   
    }
    else{
        while(j<address){
            p=p->next;
            ++j;
        }
        s=(struct Node *)malloc(sizeof(struct Node));
        s->data=AddOfNumber;
        s->next=p->next;//这里我们看见p->nexts->next所赋值 
        p->next=s;//这里的p->next被赋值了s 
    }
    return head;
}

struct Node *deletenum(struct Node *head,int NumberOfDeleta)
{
    struct Node *p,*pbef;
    int i;
    for(i=0,p=head->next,pbef=head;i<GetLenOfNode(head);i++,p=p->next,pbef=pbef->next)
    {
        if(p->data==NumberOfDeleta){    
            pbef->next=p->next;
            p->next=pbef->next;     
        }
    }
/* 
    if(p->data==NumberOfDeleta){    
        pbef->next=p->next;
        p->next=pbef->next;     
    }//别问我为什么这么写,我只是不想写判断链表长度而已 ,这种也可以解决最后一个不可删除的问题,后来还是写了一个判断 
*/ 
    return head;
}

int searchnum(struct Node *head,int NumberOfSearch)
{
    int j=1;
    struct Node *p;
    p=head->next;
    while(p!=NULL&&p->data!=NumberOfSearch){
        ++j;
        p=p->next;
    }
    return j;
}

int main(void)
{
    struct Node *head;
    head=creatlist();   
    display(head);
    printf("the len of Node is %d\n",GetLenOfNode(head));
    printf("max=%d\n",maxvalue(head)->data);
    printf("\nsortlist----------------------\n");
    head=sortlist(head);
    display(head);
    printf("\nadd a number:100 to NO.10----------------------\n");
    head=addnum(head,100,10);
    display(head); 
    printf("\ndelete a number----------------------\n");
    head=deletenum(head,0);
    display(head);
    printf("\nsearch a number:78----------------------\n");
    printf("the number is NO.%d",searchnum(head,78));
}


*/ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值