#include<bits/stdc++.h>
using namespace std;
using ll = long long;
struct stu{
int id;
int score;
struct stu *next;
};
//链表的建立
struct stu *create(){
struct stu *p1,*p2,*head;
head = NULL;
p1 = (struct stu*)malloc(sizeof(struct stu));
p2 = p1;
scanf("%d%d",&p1->id,&p1->score);
while(p1 -> id != 0){
if(head == NULL){
head = p1;
}
else{
p2 -> next = p1;
}
p2 = p1;
p1 = (struct stu*)malloc(sizeof(struct stu));
scanf("%d%d",&p1->id,&p1->score);
//想象成4步p2追p1,p2先让它的next指向p1,然后自己飞到p1的位置上
//p1又跑到下一个结点,读入那里的数据,这样循环
}
p2 -> next = NULL;
return head;
}
//链表的输出
void print(struct stu *head){
struct stu *p;
p = head;
do{
printf("%d %d\n",p->id,p->score);
p = p->next;
}while(p != NULL);
}
//链表的删除
struct stu *del(struct stu *head,int num){
struct stu *p1,*p2;
p1 = head;
if(head == NULL) {cout << "空链表";return head;}
while(p1 -> id != num && p1->next != NULL){
//未找到并且没到最后一个
p2 = p1;//p2要跟着p1,后面有用
p1 = p1 -> next;
}
if(p1 -> id == num){
if(p1 == head) head = p1 -> next;//头节点特殊考虑
else
p2 -> next = p1 -> next;
}
else printf("没有");
return head;
}
struct stu*insert(struct stu *head,struct stu *stu4){
struct stu *p0,*p1,*p2;
p0 = stu4;
p1 = head;
if(head == NULL){
head = p0;
p0 -> next = NULL;
}
else{
while((p0 -> id > p1 -> id) && (p1 -> next != NULL)){
p2 = p1;
p1 = p1 -> next;
}
}
if(p0 -> id <= p1 -> id){
if(head == p1) head = p0;
else p2 -> next = p0;
p0 -> next = p1;//插入
}
else{
p1 -> next = p0;
p0 -> next = NULL;
}
return head;
}
int main(){
struct stu *head;
head = create();
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
print(head);
printf("\n");
//删除4号
head = del(head,4);
print(head);
printf("\n");
//插入4号,分数改为80
struct stu stu4;
stu4.id = 4,stu4.score = 80;
head = insert(head,&stu4);
print(head);
return 0;
}
有注释的地方是我自己的碎碎念,就是我写链表的时候容易忘记写的地方
struct stu /*这里有个空格*/*create(){
struct stu *p1,*p2,*head;
head = NULL;
p1 = (struct stu*)malloc(sizeof(struct stu));
p2 = p1;//这句话是让p2先跟上p1
scanf("%d%d",&p1 -> id,&p1 -> score);
while(p1 -> id != 0){
if(head == NULL) head = p1;
else p2 -> next = p1;
p2 = p1;
p1 = (struct stu*)malloc(sizeof(struct stu));
scanf("%d%d",&p1 -> id,&p1 -> score);
}
p2 -> next = NULL;//这里是让p2指向的那个node的指针指向空,因为此时
//p2在表尾
return head;
}
void print(struct stu *head){
struct stu *p;
p = head;
do{
printf("%d %d\n",p -> id,p -> score);
p = p -> next;
}while(p != NULL);//这里是p不为空,而不是p -> next不为空
}
struct stu *del(struct stu *head,int num){
struct stu *p1,*p2;//只用p1和p2,插入时要用p0,p1,p
p1 = head;
if(head == NULL){printf("空链表");/*必须用分号隔开*/return head;}
//先判断链表是不是空,然后就开始找,p2紧跟着p1
while(p1 -> id != num && p1 -> next != NULL){
p2 = p1;
p1 = p1 -> next;
}
//找完后就只有两种情况,找到了或者没找到
//找到了
if(p1 -> id == num){
//找到了也分三种,要删的数在表头,在表中间,在表尾
if(p1 == head) head = p1 -> next;
//在表中间和表尾的操作是一样的
else{
p2 -> next = p1 -> next;
}
}
else printf("找不到");
return head;
}
//总结一下,找的过程就是先设置一个p1,和一个p2,p1指向表头,判断表是否为空,然后开始找
//找完后再判断是否找到,找到又分为表头和其它这两种情况
struct stu *insert(struct stu *head,struct stu *stu4){
//传入一个结构体指针用struct stu *stu4这样的格式
struct stu *p0,*p1,*p2;
p0 = stu4;//p0是用来存要插入的那个结构体的
p1 = head;
//第一种,没有节点,把插入的那个点作为第一个节点
if(head == NULL) head = p0,p0 -> next = NULL;
//第二种,存在节点
else
//开始找
//要插入的那个结构体的id大于当前的id就不断往后找
while(p0 -> id > p1 -> id && p1 -> next != NULL){
p2 = p1;
p1 = p1 -> next;
}
//又分三种,插入的在表头,在表中,在表尾
//其中在表头和表中操作相同
if(p0 -> id <= p1 -> id){
if(p1 == head) head = p0;
else p2 -> next = p0;
p0 -> next = p1;
}
else {p1 -> next = p0;p0 -> next = NULL;}
return head;
}