单链表的操作是数据结构开始的入门,包括创建,插入,删除,销毁等操作。下面是一个简单的例子,用于总结复习。
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 ;
}