C语言 单链表介绍和操作

发布于 2021-08-03 12:39:22 字数 12316 浏览 1492 评论 0

一、单链表

int main(){
  struct Test{
    int x;
    int y;
    //struct Test test;//这样编译器会报错
    struct Test *test;
  };
  return 0;
}

二、单链表结构的申明

struct Book{
  char title[128];
  char author[40];
  struct Book *next;
};

三、在单链表中插入元素

  • 头插法

#include<stdio.h>
#include<stdlib.h>

//单链表

/**
 链表是一种常见的基础数据结构。根据需求,我们可以构造出单链表、双链表、循环链表和块状链表等。链表的出现很大程度上弥补了数组的先天不足。
 */

//单链表结构的申明
struct Book{
  char title[128];
  char author[40];
  struct Book *next;
};
void getInput(struct Book *book){
  printf("请输入书名:");
  scanf("%s",book->title);
  printf("请输入作者:");
  scanf("%s",book->author);

}
void addBook(struct Book **library){
  struct Book *book,*temp;

  book = (struct Book *)malloc(sizeof(struct Book));
  if(book == NULL){
    printf("内存分配失败了!\n");
    exit(1);
  }

  getInput(book);

  if(*library != NULL){
    temp = *library;
    *library = book;
    book->next = temp;
  }else{
    *library = book;
    book->next = NULL;
  }
}
void printLibrary(struct Book *library){
  struct Book *book;
  int count = 1;
  book = library;
  while (book != NULL){
    printf("Book%d:\n",count);
    printf("书名:%s\n",book->title);
    printf("作者:%s\n",book->author);
    book = book->next;
    count++;
  }
}

void releaseLibrary(struct Book **library){
  struct Book *temp;
  while (book!=NULL) {
    temp = *library;
    *library = (*library)->next;
    free(temp)
  }
}
int main(){
  struct Book *library = NULL;//空链表

  while (1) {
    char ch;
    printf("请问是否需要录入书籍信息(Y/N):");
    do{
      ch = getchar();
    }while(ch != 'Y' && ch !='N');

    if(ch == 'Y'){
      addBook(&library);
    }else{
      break;
    }
  }

  printf("请问是否需要打印图书信息(Y/N)");
  char ch;
  do{
    ch = getchar();
  }while(ch != 'Y' && ch !='N');

  if(ch == 'Y'){
    printLibrary(library);
  }
  releaseLibrary(&library);
  return 0;
}

四、单链表的尾插法

#include<stdio.h>
#include<stdlib.h>

//单链表

/**
 链表是一种常见的基础数据结构。根据需求,我们可以构造出单链表、双链表、循环链表和块状链表等。链表的出现很大程度上弥补了数组的先天不足。
 */

//单链表结构的申明
struct Book{
  char title[128];
  char author[40];
  struct Book *next;
};
void getInput(struct Book *book){
  printf("请输入书名:");
  scanf("%s",book->title);
  printf("请输入作者:");
  scanf("%s",book->author);

}
void addBook(struct Book **library){
  struct Book *book,*temp;

  book = (struct Book *)malloc(sizeof(struct Book));
  if(book == NULL){
    printf("内存分配失败了!\n");
    exit(1);
  }

  getInput(book);

  if(*library != NULL){
    temp = *library;
    //定位单链表的尾部位置
    while(temp->next != NULL){
      temp = temp->next;
    }
    //插入数据
    temp->next = book;
    book->next = NULL;
  }else{
    *library = book;
    book->next = NULL;
  }
}
void printLibrary(struct Book *library){
  struct Book *book;
  int count = 1;
  book = library;
  while (book != NULL){
    printf("Book%d:\n",count);
    printf("书名:%s\n",book->title);
    printf("作者:%s\n",book->author);
    book = book->next;
    count++;
  }
}

void releaseLibrary(struct Book **library){
  struct Book *temp;
  while (*library!=NULL) {
    temp = *library;
    *library = (*library)->next;
    free(temp);
  }
}
int main(){
  struct Book *library = NULL;//空链表

  while (1) {
    char ch;
    printf("请问是否需要录入书籍信息(Y/N):");
    do{
      ch = getchar();
    }while(ch != 'Y' && ch !='N');

    if(ch == 'Y'){
      addBook(&library);
    }else{
      break;
    }
  }

  printf("请问是否需要打印图书信息(Y/N)");
  char ch;
  do{
    ch = getchar();
  }while(ch != 'Y' && ch !='N');

  if(ch == 'Y'){
    printLibrary(library);
  }
  releaseLibrary(&library);
  return 0;
}

以上程序执行效率较低,就是每次在尾部插入数据的时候都要便利一下整个链表。修改如下:记录单链表尾部的位置

#include<stdio.h>
#include<stdlib.h>

//单链表

/**
 链表是一种常见的基础数据结构。根据需求,我们可以构造出单链表、双链表、循环链表和块状链表等。链表的出现很大程度上弥补了数组的先天不足。
 */

//单链表结构的申明
struct Book{
  char title[128];
  char author[40];
  struct Book *next;
};
void getInput(struct Book *book){
  printf("请输入书名:");
  scanf("%s",book->title);
  printf("请输入作者:");
  scanf("%s",book->author);

}
void addBook(struct Book **library){
  struct Book *book;
  static struct Book *tail;//记录尾部位置

  book = (struct Book *)malloc(sizeof(struct Book));
  if(book == NULL){
    printf("内存分配失败了!\n");
    exit(1);
  }

  getInput(book);

  if(*library != NULL){
    tail->next = book;
    book->next = NULL;
  }else{
    *library = book;
    book->next = NULL;
  }
  tail = book;
}
void printLibrary(struct Book *library){
  struct Book *book;
  int count = 1;
  book = library;
  while (book != NULL){
    printf("Book%d:\n",count);
    printf("书名:%s\n",book->title);
    printf("作者:%s\n",book->author);
    book = book->next;
    count++;
  }
}

void releaseLibrary(struct Book **library){
  struct Book *temp;
  while (*library!=NULL) {
    temp = *library;
    *library = (*library)->next;
    free(temp);
  }
}
int main(){
  struct Book *library = NULL;//空链表

  while (1) {
    char ch;
    printf("请问是否需要录入书籍信息(Y/N):");
    do{
      ch = getchar();
    }while(ch != 'Y' && ch !='N');

    if(ch == 'Y'){
      addBook(&library);
    }else{
      break;
    }
  }

  printf("请问是否需要打印图书信息(Y/N)");
  char ch;
  do{
    ch = getchar();
  }while(ch != 'Y' && ch !='N');

  if(ch == 'Y'){
    printLibrary(library);
  }
  releaseLibrary(&library);
  return 0;
}

五、单链表的搜索

单链表的搜索就是循环遍历单链表

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//搜索单链表

/**
 有时候我们可能会对单链表进行搜索操作,比如输入书名或作者,就可以找到相关的节点数据
 */

struct Book{
  char title[128];
  char author[40];
  struct Book *next;
};
void getInput(struct Book *book){
  printf("请输入书名:");
  scanf("%s",book->title);
  printf("请输入作者:");
  scanf("%s",book->author);

}
void addBook(struct Book **library){
  struct Book *book;
  static struct Book *tail;//记录尾部位置

  book = (struct Book *)malloc(sizeof(struct Book));
  if(book == NULL){
    printf("内存分配失败了!\n");
    exit(1);
  }

  getInput(book);

  if(*library != NULL){
    tail->next = book;
    book->next = NULL;
  }else{
    *library = book;
    book->next = NULL;
  }
  tail = book;
}
void printLibrary(struct Book *library){
  struct Book *book;
  int count = 1;
  book = library;
  while (book != NULL){
    printf("Book%d:\n",count);
    printf("书名:%s\n",book->title);
    printf("作者:%s\n",book->author);
    book = book->next;
    count++;
  }
}

void releaseLibrary(struct Book **library){
  struct Book *temp;
  while (*library!=NULL) {
    temp = *library;
    *library = (*library)->next;
    free(temp);
  }
}

struct Book *searchBook(struct Book *library,char *target){
  struct Book *book;
  book = library;
  while (book!=NULL) {
    if(strcmp(book->title,target) || strcmp(book->author,target)){
      break;
    }
    book = book->next;
  }
  return book;
}

void printBook(struct Book *book){
  printf("书名:%s\n",book->title);
  printf("作者:%s\n",book->author);
}
int main(){
  struct Book *library = NULL;//空链表
  struct Book *book;
  char input[128];

  while (1) {
    char ch;
    printf("请问是否需要录入书籍信息(Y/N):");
    do{
      ch = getchar();
    }while(ch != 'Y' && ch !='N');

    if(ch == 'Y'){
      addBook(&library);
    }else{
      break;
    }
  }

  printf("请问是否需要打印图书信息(Y/N)");
  char ch;
  do{
    ch = getchar();
  }while(ch != 'Y' && ch !='N');

  if(ch == 'Y'){
    printLibrary(library);
  }
  printf("请输入书名或作者:\n");
  scanf("%s",input);
  book = searchBook(library,input);
  if(book == NULL){
    printf("很抱歉没有找到!");
  }else{
    do{
      printf("已找到符合条件的图书...");
      printBook(book);
    }while ((book = searchBook(book->next,input)) != NULL);
  }

  releaseLibrary(&library);
  return 0;
}

六、单链表的优势(中间插入)

#include<stdio.h>
#include<stdlib.h>

struct Node{
  int value;
  struct Node *next;
};

void insertNode(struct Node **head,int value){
  struct Node *previous;
  struct Node *current;
  struct Node *new;

  current = *head;
  previous = NULL;
  while(current != NULL && current->value < value){
    previous = current;
    current = current->next;
  }

  new = (struct Node *)malloc(sizeof(struct Node));
  if(new == NULL){
    printf("内存分配失败!\n");
    exit(1);
  }
  new->value = value;
  new->next = current;

  if(previous == NULL){
    *head = new;
  }else{
    previous->next = new;
  }
}

void printNode(struct Node *head){
  struct Node *current;

  current = head;
  while (current != NULL) {
    printf("%d ",current->value);
    current = current->next;
  }
  printf("\n");
}

int main(){
  struct Node *head = NULL;
  int input;

  while (1) {
    printf("请输入一个整数(输入-1表示结束):");
    scanf("%d",&input);
    if(input == -1){
      break;
    }
    insertNode(&head,input);
    printNode(head);
  }
  return 0;
}

七、单链表的删除

#include<stdio.h>
#include<stdlib.h>

struct Node{
  int value;
  struct Node *next;
};

void insertNode(struct Node **head,int value){
  struct Node *previous;
  struct Node *current;
  struct Node *new;

  current = *head;
  previous = NULL;
  while(current != NULL && current->value < value){
    previous = current;
    current = current->next;
  }

  new = (struct Node *)malloc(sizeof(struct Node));
  if(new == NULL){
    printf("内存分配失败!\n");
    exit(1);
  }
  new->value = value;
  new->next = current;

  if(previous == NULL){
    *head = new;
  }else{
    previous->next = new;
  }
}

void printNode(struct Node *head){
  struct Node *current;

  current = head;
  while (current != NULL) {
    printf("%d ",current->value);
    current = current->next;
  }
  printf("\n");
}

void deletedNode(struct Node **head,int value){
  struct Node *previous;
  struct Node *current;

  current = *head;
  previous = NULL;

  while (current != NULL && current->value != value) {
    previous = current;
    current = current->next;
  }

  if(current == NULL){
    printf("找不到匹配的节点");
    return;
  }else{
    if(previous == NULL){
      *head = current->next;
    }else{
      previous->next = current->next;
    }
    free(current);
  }
}

int main(){
  struct Node *head = NULL;
  int input;

  printf("开始测试插入整数...");
  while (1) {
    printf("请输入一个整数(输入-1表示结束):");
    scanf("%d",&input);
    if(input == -1){
      break;
    }
    insertNode(&head,input);
    printNode(head);
  }

  printf("开始测试删除整数...");
  while (1) {
    printf("请输入一个整数(输入-1表示结束):");
    scanf("%d",&input);
    if(input == -1){
      break;
    }
    deletedNode(&head,input);
    printNode(head);
  }
  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文