链表的创建,插入,删除,输出基本操作

#include<stdio.h>
#include<cstdlib>
struct student  //定义一个学生结点,结点包括值域和指针域
{
 int num;//学号
 char name[20];//姓名
 char address[20];//地址
 struct student *next;//定义结点的指针域,指向下一个结点
};
typedef struct student LIST;
LIST *CreateList();
LIST *InsertNode(LIST *h,LIST *s);
LIST *DeleteNode(LIST *h,long no);
void Display(LIST *h);

int main()
{
 LIST *head,*p;//定义指向结点的指针
 long no;//定义学号变量
 head=CreateList();//调用CreateList函数创建链表
 printf("学号 姓名 地址\n");
 Display(head);
 printf("输入要插入的结点\n");
 p=(LIST *)malloc(sizeof(LIST));//动态的生成一个结点
 scanf("%d %s %s",&p->num,&p->name,&p->address);
 head=InsertNode(head,p);
 printf("学号 姓名 地址\n");
 Display(head);
 printf("请输入删除结点的学号:\n");
 scanf("%d",&no);
 head=DeleteNode(head,no);
 if(head!=NULL)
 {
  printf("学号 姓名 地址\n");
  Display(head);
 }
 return 0;
}

/*链表的创建*/
LIST *CreateList()
{
 LIST *head,*pre,*cur;
 int i,n;
 head=NULL;
 printf("输入结点的个数:\n");
 scanf("%d",&n);
 for(i=0;i<n;i++)
 {
  cur=(LIST *)malloc(sizeof(LIST));
  cur->next=NULL;
  if(head==NULL)//表示处理当前第一个结点
   head=cur;
  else
   pre->next=cur;
  scanf("%d %s %s",&cur->num,&cur->name,&cur->address);
  pre=cur;
 }
 return head;
}

/*链表结点的插入*/
LIST *InsertNode(LIST *h,LIST *s)
{
 LIST *pre,*p;
 p=h;
 if(h==NULL)
 {
  h=s;
  s->next=NULL;
  
 }
 else
 {
  while(s->num>p->num&&p->next!=NULL)//在链表中找到要插入的位置
  {
   pre=p;
   p=p->next;
  }
  if(s->num<=p->num)
  {
   if(h==p)//若插入的结点在第一个结点之前
   {
    h=s;
    s->next=p;
   }
   else//若插入的结点在中间位置
   {
    s->next=p->next;
    p->next=s;
   }
  }
  else
  {
   p->next=s;
   s->next=NULL;
  }    
 }
 return h; 
}
/*链表结点的元素删除*/ 
LIST *DeleteNode(LIST *h,long no)
{
 LIST *q;
 LIST *pre;
 q=h;
 if(q==NULL)
 {
  printf("链表为空,不能删除结点\n");
  return NULL;
 }
 while(q->num!=no&&q!=NULL)//查找带删结点,并保存其上一个结点
 {
  pre=q;
  q=q->next;
 }
 if(q->num==no)
 {
  if(q==h)
  {
   h=h->next;
  }
  else
  {
   pre->next=q->next;
   free(q);
   printf("该结点被删除成功!");
  }
 }
 else
 {
  printf("在链表中无法找到该学号,删除失败!");
 }
 return h;
}

/*完整的链表输出*/
void Display(LIST *h)
{
 LIST *q;
 q=h;
 while(q!=NULL)
 {
  printf("学号:%d  姓名:%s  地址:%s\n",q->num,q->name,q->address);
  q=q->next;
 }
}

/**********************************NOTE*******************************
链表主要通过指针进行访问,因此,他的地址不是连续的。因此,

链表无法实现随机存储,链表的元素查找,需要从头结点开始逐

个扫描进行查找。链表是一种动态结构,相对于顺序表而言,在

执行插入和删除过程不需要移动大量的元素,执行效率大大提高。

以下就算法的四个基本操作进行总结。
链表的创建:(此处采用尾插法,并且链表元素有序)
1、定义四个指针*h,*rear,*cur,*p;分别代表头指针,尾指针(指向

链表最后一个结点的指针),当前结点的指针,辅助指针
2、将头指针指向NULL(此处为了统一所有操作,链表都带有头

结点

,h=NULL,目的是建立一个全新的链表)
3、为全新的链表添加结点,由于是动态的,创建一个结点先要

申请内存,然后为其赋值,最后将其插入链表。由于链表的三个

部分(首部,尾部,中间)的不同,一般插入时要予以判断,

进行不同操作。具体如下:(初始时p=h)
1)申请一个结点并初始化
 cur=(LIST *)malloc(sizeof(LIST));
 cur->next=NULL;
 scanf("%d %s %s",&cur->num,&cur->name,&cur->address);//此步根据结点的定义来决定
2)插入链表
   当链表为空时
   if(h==NULL)
     h=cur;
    当链表不空时,通过某一参值比较,知道插入的位置(此处以num为参值)
    while(p->num<cur->num&&p!=NULL)
     p=p->next;
    if(p==h)//当插入位置为第一个结点时
    {
     cur->next=h->next;
     h=cur;
    }
    else if(p->next==NULL)//当插入位置为最后一个结点之后
    {
     p->next=cur;
     cur->next=NULL;//可不要
    }
    else//当插入位置在中间时
    {
     cur->next=p->next;
     p->next=cur;
    }
    插入完成,返回链表return h;

链表的插入:略,操作与链表的创建相同

链表的删除:
    查找与删除,根据删除的参值进行查找删除元素前一个元素的位置(此处参值为num,前一元素指针*pre)
       1)如果链表为空,则查找失败,输出提示信息
       if(h==NULL)
        printf("链表为空,查找失败!\n")
       else
       {
         while(p->num!=no&&p!=NULL)//查找待删元素及其前一个结点的位置
         {
          pre=p;
          p=p->next;
         }
         if(p->num==no)
         {
          if(p==h)//当待删结点为第一个结点
           h=pre->next;
          else
           pre->next=p->next;
         }
         else
          printf("链表中不存在这个结点,删除失败!\n");
     }
     return h;

链表的输出:
     while(q!=NULL)
 {
  printf("学号:%d  姓名:%s  地址:%s\n",q->num,q->name,q->address);
  q=q->next;
 }

原文地址:https://www.cnblogs.com/wjg1997/p/9651797.html

时间: 2024-11-03 21:08:12

链表的创建,插入,删除,输出基本操作的相关文章

JavaScript之jQuery-3 jQuery操作DOM(查询、样式操作、遍历节点、创建插入删除、替换、复制)

一.jQuery操作DOM - 查询 html操作 - html(): 读取或修改节点的HTML内容,类似于JavaScript中的innerHTML属性 文本操作 - text(): 读取或修改节点的文本内容,类似于JavaScript中的textContent属性 值操作 - val(): 读取或修改节点的value属性值,类似于 JavaScript 中的value值 属性操作 - attr(): 读取或者修改节点的属性 - removeAttr(): 删除节点的属性 二.jQuery操作

使用OC实现单链表:创建、删除、插入、查询、遍历、反转、合并、判断相交、求成环入口

一.概念 链表和数组都是一种线性结构,数组有序存储的,链表是无序存储的. 数组中的每一个元素地址是递增或者递减的关系,链表的每一个节点的地址没有此规律,它们是通过指针的指向连接起来. 链表种类:单链表.双向链表.循环链表.双向循环链表 单链表:一个数据域data.一个后继指针域next.也即:上一个节点指向下一个节点,尾节点指向空. 双向链表:一个数据域data.一个前驱指针域previous.一个后继指针域next.也即:上一个节点和下一个节点互相指向,尾节点指向空. 循环链表:一个数据域da

链表 创建 插入 删除 查找 合并

最近学习了一下单链表的操作,将代码保存如下,供以后查看. 链表创建: 1.先建立一个不含数据的头指针*head,头指针的链接域为NULL. 2.声明一个用于暂存新申请空间的指针*pc,一个用于保存创建的链表的指针*r,令*r指向*head. 3.在循环中,为指针*pc申请空间,并给数据域赋值,head->next = pc, pc->next = NULL, head = pc. #define _CRT_SECURE_NO_DEPRECATE /*取消scanf,printf不安全之类的错误

[PHP] 数据结构-链表创建-插入-删除-查找的PHP实现

链表获取元素1.声明结点p指向链表第一个结点,j初始化1开始2.j<i,p指向下一结点,因为此时p是指向的p的next,因此不需要等于3.如果到末尾了,p还为null,就是没有查找到 插入元素1.插入元素和查找类似,找到位置后2.生成新的结点s, s->next=p->next p->next=s; 删除元素1.删除元素,找到位置后2.绕过一下,q=p->next p->next=q->next; <?php class Node{ public $data

双向链表排序、插入删除等基本操作

未考虑性能,只是能完成基本功能,应付公司考试而已. 1 // list.cpp : 定义控制台应用程序的入口点. 2 // 3 4 #include "stdafx.h" 5 #include<stdlib.h> 6 typedef struct tag_data 7 { 8 int age; 9 }Data; 10 typedef struct tag_node Node; 11 typedef struct tag_node 12 { 13 Node* pnext; 1

「C语言」单链表/双向链表的建立/遍历/插入/删除

最近临近期末的C语言课程设计比平时练习作业一下难了不止一个档次,第一次接触到了C语言的框架开发,了解了View(界面层).Service(业务逻辑层).Persistence(持久化层)的分离和耦合,一种面向过程的MVC的感觉. 而这一切的基础就在于对链表的创建.删除.输出.写入文件.从文件读出...... 本篇文章在于巩固链表的基础知识(整理自<C语言程序设计教程--人民邮电出版社>第十章),只对链表的概念及增删改查作出探讨,欢迎指教. 一.链表结构和静态/动态链表 二.单链表的建立与遍历

数据结构:链表的基本操作(创建,删除,插入,逆序,摧毁)

代码注释比较详细: #include <iostream> #include <cstdlib> using namespace std; struct Node{ int data; Node* next; }; Node* head = NULL; bool create() { head = (Node*)malloc(sizeof(Node)); if(NULL == head) return false; head->data = 0; head->next

单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(LNode) #

链表(二)——单向链表的基本操作(创建、删除、打印、结点个数统计)

1.指针的联动 通过两个指针分别指向前驱和后继结点,并在单向链表上进行移动,当指针指向待处理的结点时,该结点的前驱也有指针指向. 2.设有一个无序单向链表,且数据域的值均不相同,使指针pmin指向最小值结点,并使指针prem指向最小值结点的前驱结点: 代码片段: for(p = head; p; q = p, p = p->next) { if(pmin->data > p->data) { pmin = p; prem = q; } } 3.单向链表的删除算法 注:使用mallo