实战数据结构(1)_单链表的操作

      单链表的操作是数据结构开始的入门,包括创建,插入,删除,销毁等操作。下面是一个简单的例子,用于总结复习。

1.创建一个带头结点的链表,其实就是一个头节点,然后其后继元素next为NULL.所有的节点元素都是附加在其后的。

2.插入链表,主要传过来头节点和要插入的位置,插入的时候,也是很简单,无非是需要两个指针,一个前驱指针pre,一个当前插入位置的指针cur。 在堆上开辟新的节点后,其节点指针为p;所以插入的顺序为:pre->next=p;p->next=cur;这样就完成了一个节点的插入,同时在插入的时候,还要考虑位置的合法性,以及是不是最后一个位置插入,如果是最后一个位置插入,就只需要,cur和p.直接,cur->next=p;

3.删除节点操作,也是和上面类似,需要 pre.cur.pre->next=cur->next;free(cur);OK

4.查找元素:

<1>按位置查找,当然是先找到位置,因为单链表的位置都是需要遍历的,先用循环找到要查找的位置指针,然后打印出数据元素。

<2>按值查找,就是根据值来匹配,比如查找序号为某个数的学生数据,也是要遍历,然后打印5.销毁链表,因为这种动态开辟的链表,都是在堆上的开辟内存,在不用的时候,必须释放掉,销毁链表也是,依次free(p),用循环。总结: 在对链表操作的过程中,c的用法还是有点问题,还是不能一次性编码正确,这里犯了scanf(“%S,%S”)的错误,用scanf来进行接受两个字符串的操作,这里的","将也会被认为是第一个字符串的字符,并没有起到隔离两个字符串的作用。而且对单个字符操作的时候,要注意,回车也是一个字符,将被接受进入内存,只是在内存中。所以在进行接受两个字符的时候,用scanf(“%S %S”)中间用空格隔开,这个问题先记着在去看。

#include <stdio.h>  
#include <stdlib.h>  
  
typedef struct node  
{     
    int num;  
    char name[10];  
    char score[10];  
    struct node *next;  
}stuinfo;  
static int length;  
  
void CreateList(stuinfo *h,int x);  
void printfSingleList(stuinfo *h);  
void InsertSingleList(stuinfo *h,int pos);  
void DeleteSingleList(stuinfo *head,int num);  
void findelement_bypos(stuinfo *head,int pos);  
void findelement_bynum(stuinfo *head,int num);  
int main()  
{     
    static stuinfo *head;  
    head=(stuinfo *)malloc(sizeof(stuinfo)); //开辟一个头结点  
    if(NULL==head)  
    {  
        printf("malloc申请失败");  
        exit(-1);  
    }  
    head->next=NULL;  
    while(1)  
    {  
        printf("1---创建链表\n");  
        printf("2---插入链表\n");  
        printf("3---删除链表\n");  
        printf("4---打印当前链表元素\n");  
        printf("5---按位置查找\n");  
        printf("6---按学号查找\n");  
        printf("7---退出\n");  
        int choice,num;  
        printf("请输入选择:\n");  
        scanf("%d",&choice);  
        switch(choice)  
        {  
            case 1:  
                {     
                    printf("请输入新建元素个数\n");  
                    scanf("%d",&num);  
                    length=num;  
                    CreateList(head,num);  
                    break;  
                }  
            case 2:  
                {   printf("请输入插入位置\n");  
                    scanf("%d",&num);  
                    InsertSingleList(head,num);  
                    break;  
                }  
            case 3:  
                {   printf("请输入删除的位置\n");  
                    scanf("%d",&num);  
                    DeleteSingleList(head,num);  
                    break;  
                }  
            case 4:  
                {     
                    printfSingleList(head);  
                    break;  
                }  
            case 5:  
                {   printf("请输入查找的位置\n");  
                    scanf("%d",&num);  
                    findelement_bypos(head,num);  
                    break;  
                }  
            case 6:  
                {  
                    printf("请输入查找的学号\n");  
                    scanf("%d",&num);  
                    findelement_bynum(head,num);  
                    break;  
                }  
            case 7:  
                {  
                    return 1;  
                }  
            default:  
                break;  
        }     
    }  
        return 1;  
}  
  
  
void CreateList(stuinfo *h,int x)  
{  
    stuinfo *head=h;   
    stuinfo *pre=head;  
    stuinfo *newnode;  
    for(int i=1;i<=x;i++)  
    {     
        if(NULL==(newnode=(stuinfo *)malloc(sizeof(stuinfo))))//开辟一个新节点  
        {  
            printf("malloc申请失败");  
            return ;  
        }  
    //  newnode->next=NULL;  //在每个节点都分配NULL  
        printf("请输入第%d个学生信息\n",i);  
        scanf("%d %s %s",&(newnode->num),newnode->name,newnode->score);  
        pre->next=newnode;  
        pre=newnode;  
    }  
    pre->next=NULL;  
    return ;  
}  
  
void printfSingleList(stuinfo *h)  
{  
    stuinfo *p=h->next;  
    if(p==NULL)  
    {  
        printf("当前链表为空\n");  
        exit(-1);  
    }  
    while(p!=NULL)  
    {  
        printf("学号%d 姓名 %s 分数 %s\n",p->num,p->name,p->score);  
        p=p->next;  
    }  
    return ;  
}  
  
void InsertSingleList(stuinfo *h,int pos)  
{     
      
    if(pos<1||pos>length+1)	  //位置时候无效  
    {   printf("插入位置error\n");  
        return ;  
    }  
    else   //位置有效
    {     
        stuinfo *pre=h,*cur;  
        if(NULL==(cur=(stuinfo *)malloc(sizeof(stuinfo))))//开辟一个新节点  
        {  
            printf("malloc申请失败");  
            return ;  
        }  
        printf("请输入插入信息\n");  
        scanf("%d %s %s",&(cur->num),cur->name,cur->score);  
           
        for(int i=1;i<pos;i++)  //查找前驱节点
			 pre=pre->next;

		cur->next=pre->next; //
		pre->next=cur;  
		length++; //更新长度  
		return ;  
    }  
}  
  
void DeleteSingleList(stuinfo *head,int pos)  
{  
    if(pos<1||pos>length)  
    {  
        printf("删除位置错误\n");  
        return;  
    }  
    else  
    {  
        stuinfo *pre=head;
        for(int i=1;i<pos;i++) //查找要删除的前驱节点
				pre=pre->next;
		stuinfo *p=pre->next;
        pre->next=p->next;  
        free(p);  
        length--;  
        return ;  
    }  
}     
 /************************************************************************/
 /* 总结:
插入和删除其实都是在找前驱指针pre.
1.插入的时候,先更新新节点的Next域,然后在更新pre的next域
2.删除时候,要记得p=pre->next不然会出错。
   不能:	pre->next=pre->next->next;
			free(pre->next)
                                                                  */
 /************************************************************************/
void findelement_bypos(stuinfo *head,int pos)  
{  
    if(pos<1||pos>length)  
    {  
        printf("查找位置error\n");  
        return ;  
    }  
    else  
    {  
        stuinfo *p=head;  
        for(int i=0;i<pos;i++)  
            p=p->next;  
        printf("%d %s %s\n",p->num,p->name,p->score);  
    }  
    return  ;  
}  
  
  
void findelement_bynum(stuinfo *head,int num)  
{  
    stuinfo *p=head->next;  
    while(p->num!=num)  
        p=p->next;  
    if(NULL==p)  
    {  
        printf("查找不到\n");  
        return ;  
    }  
    else {  
        printf("学号%d 姓名 %s 分数 %s\n",p->num,p->name,p->score);  
    }  
    return ;  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值