链表的一些基本操作:动态链表、插入和删除等

来源:互联网 发布:淘宝搜不到以前的订单 编辑:程序博客网 时间:2024/06/05 04:01
#include<stdio.h>
#include<malloc.h>
#define LEN sizeof(struct Student)


/*
*author:hacker_crazy
*time:2014.9.17 
*/ 




//结构体:学号num、分数score、结构体指针*next 
struct Student{
int num;
int score;
struct Student *next;
};




int n;//全局变量:记录节点数 


/*---------------函数声明--------------------*/
 typedef struct Student * stuNode;
stuNode Create();//创建一个新的链表
void Print(stuNode head);    //通过传入的链表头指针打印整个链表 
stuNode Delete(stuNode head,int num);    //通过传入的链表头指针和学生学号删除节点  
stuNode Insert(stuNode head,stuNode NewStudent);    //依照学生学号的顺序向链表中插入新元素 
 
 
 
//创建一个新的链表 
struct Student * Create(){
//表头:指向的是整个链表的首地址
struct  Student *head; 
//p1:下一个节点的地址;p2:上一个节点的地址
struct Student *p1,*p2; 
//开辟一个大小为为LEN的空间 (length), 
p1=p2=(struct Student *)malloc(LEN);
n=0;
head=NULL;//将表头设为空 
printf("请输入学号和分数:");
scanf ("%d %d",&p1->num,&p1->score);


while((p1->num)!=NULL){
n=n+1;
if (NULL==head){
//这里是将 p1的地址储存在head中
head=p1; 
}else{
//这里的意思是说:将p1的地址存储在p2的next中,p2 是上一个节点的next哦!
p2->next=p1; 
}
//这里的意思是:将节点向下一位移动一格
p2=p1; 
p1=(struct Student *)malloc(LEN);
printf("请输入学号和分数:");
scanf ("%d %d",&p1->num,&p1->score);
}
//将节点的结尾设为空 
p2->next=NULL;
return head; 
}


//通过传入的链表头打印 指针打印整个链表
void Print(struct Student *head){
struct Student *p; 
p=head;
//判断链表是不是为空 
if (NULL==head){
printf("链表为空!\n");
}else{
printf("个数n为:\t%d\n",n);
//打印循环中的链表 
while (p!=NULL){
printf("%d\t%d\n",p->num,p->score);
//指针指向下一个节点 
p=p->next;
}
}



//通过传入的表头指针和学号删除学生信息
struct Student *Delete(struct Student *head,int num){
struct Student *p1;
struct Student *p2;
p1=head;
//判断是不是空链表 
if(NULL==head){
printf("链表为空!\n");
     return head;
}
//遍历节点,判断当前节点是不是需要删除的节点及是否为尾节点
     //如果找到相应节点,或者已经遍历到尾节点就跳出循环 
while (p1->num!=num && p1->next!=NULL){
//p2指的是当前节点的地址 
p2=p1;
//p1被赋值为下一个节点的地址 
p1=p1->next;
}

//判断是否找到相应节点 
if (p1->num==num){
//要删除的节点是不是链表的第一个节点
if (head==p1){
//如果是,就将头指针指向该节点的后一个节点
head=p1->next;
}else{
//如果不是,就将该节点的前一个节点的指针指向该节点的后一个节点 
p2->next=p1->next;
}

//节点数量减少一个 
n=n-1;
//输出的是删除的学号 
printf("%d已经删除!\n",num);
}else {
printf("链表中没有要删除的元素.\n");
}
return head;



//依照学生学号的顺序向链表中插入新元素 
struct Student *Insert(struct Student *head,struct Student *NewStudent){
struct Student *p0;
struct Student *p1;
struct Student *p2;
p0=NewStudent;
p1=head;
//判断链表是否为空,如果是空链表,就将新节点作为第一个节点 
if(head==NULL){
head=p0;
p0->next=NULL;
}else{
//遍历每一个节点中的学号,与新学号比较大小
         //如果找到一个学号比新学号大,就将新学号的节点插入它之前 
         //如果尾节点的学号仍比新学号小,就将新节点插入到链表尾部 
         while((p0->num)>(p1->num) && (p1->next)!=NULL){
          p2=p1;
          p1=p1->next;
         }
           //找到一个比新学号大的节点 
           if ((p1->num)>=(p0->num) ){
            //判断是不是表头,如果是,则将新节点设为表头 
  if (head==p1) {
  head=p0;
  }else{
  p2->next=p0;
  }
  p0->next=p1;
           }else{
            p1->next=p0;
            p0->next=NULL;
           }
}
//链表长度增加1 
n=n+1;
printf("%d插入成功\n",NewStudent->num);
return head;
}
int main(){
struct Student *head;
struct Student *NewStudent;
int num;
//调用创建一个链表的函数,输入若干数据 ;并返回表头 
head=Create();
Print(head);
//删除操作
printf("请输入要删除的学号:"); 
scanf("%d",&num);
while(num!=0){
head=Delete(head,num);
Print(head);
//多次执行 
printf("请输入要删除的学号:"); 
scanf("%d",&num);
}

//插入操作
printf("请输入要插入的节点:"); 
//申请LEN大小的空间 
NewStudent=(struct Student *)malloc(LEN);
scanf ("%d %d",&NewStudent->num,&NewStudent->score);
while(NewStudent->num!=0){
head=Insert(head,NewStudent);
//多次执行 
printf("请输入要插入的节点:");
NewStudent=(struct Student *)malloc(LEN);
scanf ("%d %d",&NewStudent->num,&NewStudent->score); 
}
Print(head);
// return 0;

}




0 0
原创粉丝点击