创建链表
情况一:创建的链表结点数通过输入n可知,n作为参数传入函数
struct Student *createList(int n){
struct Student *head,*end,*node; //定义头节点,尾节点,新节点
head=(struct Student *)malloc(sizeof(struct Student)); //给头节点申请内存
end=head; //空表则头尾地址一致
printf("请输入学生姓名、成绩:\n");
for(int i=0;i<n;i++){ //for循环向链表添加数据
node=(struct Student *)malloc(sizeof(struct Student));//给新节点申请内存
scanf("%s%d",node->name,&node->score); //给数据域赋值
end->next=node; //使新节点链入上一节点后面
end=node; //新节点变尾结点,供下一新节点链入
}
end->next=NULL; //end的指针域置空
return head; //返回头节点地址
}
情况二:创建的链表结点数未知,有输入结束标志-1或0等
struct Student *createList(){
struct Student *head,*node,*end;
head=(struct Student *)malloc(sizeof(struct Student));
end=head;
char m[10]; //m变量存姓名
int n; //n变量存成绩
printf("请输入学生姓名、成绩:");
while(1){
scanf("%s%d",m,&n);
if(n==0) break;
node=(struct Student *)malloc(sizeof(struct Student));
node->score=n;
strcpy(node->name,m);
end->next=node;
end=node;
}
end->next=NULL;
return head;
}
打印链表
void printList(struct Student *head){
struct Student *p=head->next; //头结点数据域无存值
while(p!=NULL){
printf("%5s%5d\n",p->name,p->score);
p=p->next;
}
}
删除节点
情况一:删除第n个节点(头节点不算第一个),n作为参数传入函数 --------先找后删
void deleteNode(struct Student *head,int num){
struct Student *pr=head,*t=head;
int i=0;
while(i<num&&t!=NULL){ //到达指定节点,t指向要删除的节点,pr指向要删除结点的上一节点
pr=t;
t=t->next;
i++;
}
if(t!=NULL){ //使t不越界(若有三个节点,num=4则while后t指向NULL,需排除该情况
pr->next=t->next; //断开t指向的节点,连接t前后的节点
free(t); //释放t指向的节点的内存空间
}else{
printf("该节点不存在!\n");
}
}
情况二:删除score与s相同的节点(可能不止一个)--------边找边删
void deleteNode(struct Student *head,int s){
struct Student *pr=head,*t=head;
while(pr->next!=NULL){
if(pr->next->score==s){
t=pr->next; //t指向要删除的节点
pr->next=t->next;
free(t);
}else{
pr=pr->next; //未找到时,pr一直往前走,t指向头结点不动
}
}
}
插入节点
void insertNode(struct Student *head,int n)//插入到第n个之后(若n=3,则插入后新节点是第四个节点)
{
struct Student *t=head,*node;
node=(struct Student *)malloc(sizeof(struct Student));
printf("请输入新增学生数据:");
scanf("%s%d",node->name,&node->score);
int i=0;
while(i<n&&t!=NULL){//t指向要插入节点的位置
t=t->next;
i++;
}
//当插入位置是尾节点时,则在尾节点后再插入一个节点,并让尾节点的指针域指向新建节点,使新建节点的指针域置空
if(t!=NULL){
node->next=t->next;//将新建节点的地址指向将要插入节点的后一个节点
t->next=node;//使插入节点的地址指向新建节点
}else
printf("该节点不存在!\n");
}
链表拼接
程序功能:输入若干个学生成绩(输入-1为结束标志),建立两个已按升序排序的单向链表,头指针分别为list1、list2,把两个链表拼成一个升序排序的新链表,并输出新链表信息。要求自定义函数,实现将两个链表拼成一个链表,并返回拼组后的新链表。
#include <stdio.h>
#include <stdlib.h>
struct ListNode {
int score;
struct ListNode *next;
};
//创建链表并排序
struct ListNode *createlist(){
int num;
struct ListNode *head,*node,*pr,*t;
head=(struct ListNode *)malloc(sizeof(struct ListNode));
head->next=NULL;
printf("请输入数据:\n");
while(1){
scanf("%d",&num);
if(num == -1) break;//输入-1为结束标志
node=(struct ListNode *)malloc(sizeof(struct ListNode));
node->score = num;
pr = head;
t = head->next;//注意t每次都是在head后面开始
while(t!=NULL && t->score<=num){//寻找新结点插入位置
pr = t;
t = t->next;
}
node->next = t;
pr->next = node;
}
return head;
}
//按升序合并表一和表二
struct ListNode *mergelist(struct ListNode *list1,struct ListNode *list2)
{
struct ListNode *res,*t;
res=(struct ListNode *)malloc(sizeof(struct ListNode));
t=res;
list1=list1->next;
list2=list2->next;
while(list1&&list2){ //表一和表二均不为空
if(list1->score>list2->score){
t->next=list2; //t的指针域指向较小数的节点
list2=list2->next;
t=t->next;
}
else{
t->next=list1;
list1=list1->next;
t=t->next;
}
}
//若表一和表二的数据个数不相同,则剩余数据链入新链表
if(list1){
t->next=list1;
}
if(list2){
t->next=list2;
}
return res;
}
void printlist(struct ListNode *head){
struct ListNode *p=head;
p=head->next;
while(p!=NULL){
printf("%d ", p->score);
p=p->next;
}
}
int main(){
struct ListNode *list1, *list2,*res;
list1 = createlist();
list2 = createlist();
res= mergelist(list1, list2);
printlist(res);
return 0;
}