AAA链表

0 阅读6分钟

一、输入链表长度n,再输入n个数为链表每个结点值,最后输出

1.尾插法:每次创建的新结点在链表尾部
#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;
void inser(Links **temp,int val){
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=NULL;
    (*temp)->next = newlink;
    *temp = newlink;
}
void print(Links *head){
for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}
int main(){
  int n,val;
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  Links *temp=head;
  scanf("%d",&n);
  for(int i=0;i<n;i++){
     scanf("%d",&val);
     inser(&temp,val);
  }
  print(head);
return 0;
}
2.头插法:每次创建的新结点在链表头部
#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;
void inser(Links **head,int val){
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=(*head)->next;
    (*head)->next=newlink;

}
void print(Links *head){
for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}
int main(){
  int n,val;
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  scanf("%d",&n);
  for(int i=0;i<n;i++){
     scanf("%d",&val);
     inser(&head,val);
  }
  print(head);
return 0;
}

二、在第k个数后面插入

创建值为-1,-2,-3的链表,输入整数k,在链表第k个数后面插入新结点newlinks

#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;
void inser(Links **temp,int val){
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=NULL;
    (*temp)->next = newlink;
    *temp = newlink;
}
void print(Links *head){
for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}

int main(){
  int k; //整数k
  //创建链表
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  Links *temp=head;
  scanf("%d",&k);
  for(int i=1;i<=3;i++){
     inser(&temp,-i);
  }
  
    //newlinks新节点
    Links *newlinks=(Links *)malloc(sizeof(Links));
    newlinks->a=10;
    newlinks->next=NULL;
    
    //核心逻辑
    //1.找到第k个结点
    int cnt = 1;
    for(Links *i = head -> next; i != NULL; i = i -> next, cnt ++) {
        if(cnt == k) { //在第k个结点后插入新节点newlinks
            newlinks->next=i->next;
            i->next=newlinks;
        }
    }
  print(head);
return 0;
}

三、删除指定值的结点

创建一个值为1,2,3,4,5链表,删除值为3的结点

#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;
void inser(Links **temp,int val){
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=NULL;
    (*temp)->next = newlink;
    *temp = newlink;
}
void print(Links *head){
for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}

int main(){
  //创建链表
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  Links *temp=head;
  for(int i=1;i<=5;i++){
     inser(&temp,i);
  }
  
    /*删除当前节点逻辑: 前一个节点->next = 前一个节点->next->next; 
        当前节点只有next向后的指针,无法找到前一个节点,而删除操作改变前一个节点的next域实现删除*/
    for(Links *i = head; i->next != NULL; i = i -> next) {
        if(i->next->a == 3) { //当前节点的下一个节点值为3时,删除下一个结点
            i->next=i->next->next;
        }
    }
  print(head);
return 0;
}

四、删除第K个结点

创建一个值为-1,-2,-3,-4,-5链表,删除第3个结点

#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;
void inser(Links **temp,int val){
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=NULL;
    (*temp)->next = newlink;
    *temp = newlink;
}
void print(Links *head){
for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}

int main(){
  //创建链表
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  Links *temp=head;
  for(int i=1;i<=5;i++){
     inser(&temp,-i);
  }
  
  
    /*删除第K个结点逻辑:通过第k-个结点才能删除第k个结点,只需找到第k-1个结点即可*/
    int cnt = 1; //令虚拟头结点为1,这样cnt=k时相当于第k-1个节点
    for(Links *i = head; i->next != NULL; i = i -> next,cnt++) {
        if(cnt == 3) { 
            i->next=i->next->next;
        }
    }
  print(head);
return 0;
}

五、输出链表最大/最小值

创建一个值为1,2,10,8,-1,-9的链表,输出最大最小值

#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;
void inser(Links **temp,int val){
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=NULL;
    (*temp)->next = newlink;
    *temp = newlink;
}
void print(Links *head){
for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}

int main(){
  //创建链表
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  Links *temp=head;
  inser(&temp,1);inser(&temp,2);inser(&temp,10);inser(&temp,8);inser(&temp,-1);inser(&temp,-9);
  
  //找最大值,定义辅助结点,记录当前最大值是哪一个节点
  int max = -99999;
  Links* maxx = (Links*)malloc(sizeof(Links));
  temp->next=NULL;
  for(Links *i = head -> next; i != NULL; i = i -> next) {
      if(i->a > max) { //找到有比当前最大值大的,更新最大值,更新maxx结点
          max = i->a;
          maxx = i;
      }
  }
  printf("%d\n", maxx->a);
  
//找最小值
  int min = 99999;
  Links* minn = (Links*)malloc(sizeof(Links));
  temp->next=NULL;
  for(Links *i = head -> next; i != NULL; i = i -> next) {
      if(i->a < min) { 
          min = i->a;
          minn = i;
      }
  }
  printf("%d", minn->a);
return 0;
}

难:六、翻转链表

给定一个值为1,2,3,4,5的链表,将链表翻转

思路:创建一个新链表,之后遍历给定的链表,每遍历一个节点就用头插法往新链表中插入

#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;

void inserHead(Links **head,int val){  //头插法函数
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=(*head)->next;
    (*head)->next=newlink;
}

void print(Links *head){
    for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}

int main(){
  //假设为给定的链表1,2,3,4,5
  Links* head = (Links*)malloc(sizeof(Links));
  head->next=NULL;
  for(int i=5;i>=1;i--){
      inserHead(&head, i);
  }
  
  //核心逻辑
  //1.创建新链表
   Links* newHead = (Links*)malloc(sizeof(Links));
   newHead->next=NULL;
   
   //2.遍历给定的链表,头插
   for(Links *i = head -> next; i != NULL; i = i -> next) {
       inserHead(&newHead, i->a);//头插法函数
   }
   print(newHead);
    return 0;
}

难:七、有序合并两个有序链表

输入两个有序链表,并有序的合并

例如:给定两个链表分别为1,3,5和2,4,6,8, 合并为1,2,3,4,5,6,8

思路:指针i从头节点开始遍历链表1,指针j从头结点开始遍历链表2, 创建一个新链表,ij所指结点值小的,插入到链表尾部,并移动该结点对应的指针i/j, 例如i对应节点值为2,j节点值为3,将2尾插入新链表,之后i后移一位,j不变。一直循环直到遍历完其中一个链表,此时另一个链表还未遍历完,再将该链表后续值全部尾插入新节点

#include <stdio.h>
#include <stdlib.h>
typedef struct Links{
    int a;
    struct Links* next;
}Links;

void inserHead(Links **head,int val){  //头插法函数
    Links *newlink=(Links *)malloc(sizeof(Links));
    newlink->a=val;
    newlink->next=(*head)->next;
    (*head)->next=newlink;
}

void print(Links *head){
    for(Links *i = head -> next; i != NULL; i = i -> next) {
        printf("%d ",i->a);
    }
      
}


//核心函数:合并两个升序链表
Links* mergeTwoSortedLists(Links* head1, Links* head2) {
    // 1. 创建新链表
    Links* newHead = (Links*)malloc(sizeof(Links));
    newHead->next = NULL;
    
    Links* temp = newHead; 

    Links* i = head1->next; // 指针i遍历链表1
    Links* j = head2->next; // 链表j遍历链表2

    while (i != NULL && j != NULL) { //有一个链表被遍历完就结束
        if (i->a < j->a) { //i对应的节点值小,将i节点插入新链表并后移
            temp->next = i;
            i = i->next;
        } else {
            temp->next = j;
            j = j->next; 
        }
        temp = temp->next; 
    }

    // 处理剩余节点(其中一个链表已遍历完,直接拼接剩余部分)
    if (i != NULL) {
        temp->next = i;
    }
    if (j != NULL) {
        temp->next = j;
    }

    return newHead;
}


int main(){
  //链表1 3 5
  Links* head1 = (Links*)malloc(sizeof(Links));
  head1->next=NULL;
  for(int i=5;i>=1;i-=2){
      inserHead(&head1, i);
  }
  
 //链表2 4 6 8
  Links* head2 = (Links*)malloc(sizeof(Links));
  head2->next=NULL;
  for(int i=8;i>=2;i-=2){
      inserHead(&head2, i);
  }
    
  Links* mergedHead = mergeTwoSortedLists(head1, head2);
    print(mergedHead);
    return 0;
}