单链表的建立及插入删除操作 c语言
- 格式:doc
- 大小:27.00 KB
- 文档页数:3
c语言单链表的基本操作C语言的单链表是一种常见的数据结构,常常用于存放数据的操作。
在实际开发中,掌握C语言单链表的基本操作是非常重要的。
下面,我们将分步骤阐述C语言单链表的基本操作。
第一步:定义单链表节点的结构体单链表的每个节点都有三个部分组成:数据域、指针域和链头。
其结构体如下所示:```struct Listnode{int data; //数据域struct Listnode* next; //指针域};```第二步:创建单链表创建单链表的方法有很多,这里我们介绍一个使用头插法的创建方法。
该方法需要定义一个头节点,然后将新的节点插到头节点后面。
代码如下所示:```struct Listnode * create(){struct Listnode * head = NULL; //定义头节点为空int x; //定义数据变量xprintf("请输入数据:");while (scanf("%d", &x) != EOF) //判断当前输入是否结束{struct Listnode * p = (structListnode*)malloc(sizeof(struct Listnode)); //利用malloc函数为新节点分配内存p->data = x; //将x的值存储进新开辟的节点p->next = head; //将head指向的节点作为p节点的下一个节点head = p; //然后将p作为新的head}return head; //返回头节点}```第三步:遍历单链表遍历单链表需要用到while循环,直到链表中没有节点可以遍历。
遍历的过程中,可以利用指针打印节点的数据值。
代码如下所示:```void traverse(struct Listnode *head){if (head == NULL) //判断链表是否为空printf("链表为空!");struct Listnode * p = head; //定义一个指向head节点的指针 while (p != NULL) //当指针p不为空时{printf("%d ", p->data); //打印节点中的数据p = p->next; //指针p指向下一个节点}}```第四步:插入节点在插入节点前,需要先找到插入位置的前一个节点。
一、实验目的1.掌握单链表的基本操作:插入、删除、查找以及表的合并等运算。
2.掌握运用C语言上机调试单链表的基本方法。
二、实验任务1.试编写在单链表上实现插入和删除的算法。
三、程序流程图四、测试过程及结果五、总结1.程序特点:最小化、模块化、for循环。
2.单链表特点:动态分配内存、必须从已知指针逐一查找数据、通过改变数据间的链接改变顺序。
附录程序清单#include <stdio.h>#include <stdlib.h>struct NODE{int data;NODE *next;};NODE *creatlink(){NODE *head,*p,*s;int i,n;head=(NODE *)malloc(sizeof(NODE));p=head;scanf("%d",&n);for(i=0;i<n;i++){s=(NODE *)malloc(sizeof(NODE));scanf("%d",&s->data);p->next=s;p=s;}p->next=0;return head;}void print(NODE *p){for(p=p->next;p!=0;p=p->next)printf("%d ",p->data);printf("\n");}void insert(NODE *p,int i,int x){NODE *s;int j;for(j=1;j<i;j++)p=p->next;s=(NODE *)malloc(sizeof(NODE));s->data=x;s->next=p->next;p->next=s;}void Delete(NODE *p,int i){NODE *s;int j;for(j=1;j<i;j++)p=p->next;s=p->next;p->next=s->next;free(s);}void main(){int i,x;NODE A=*creatlink();scanf("%d%d",&i,&x);insert(&A,i,x);print(&A);scanf("%d",&i);Delete(&A,i);print(&A);}。
算法描述 | 单链表中插入、删除操作1. 前言单链表是一种常见的数据结构,它由节点组成,每个节点包含数据和指向下一个节点的指针。
在实际应用中,我们经常需要对单链表进行插入和删除操作,以维护和操作数据。
本文将以深度和广度的方式,探讨单链表中插入、删除操作的算法描述,帮助读者全面理解并掌握这一重要的数据结构操作。
2. 单链表的基本结构单链表由多个节点组成,每个节点包含两部分:数据和指向下一个节点的指针。
我们来看一下单链表的基本结构:```pythonclass Node:def __init__(self, data):self.data = dataself.next = None```在上述代码中,我们定义了一个节点类Node,每个节点包含数据部分data和指向下一个节点的指针部分next。
这样的设计使得单链表能够灵活地扩展和操作,便于插入和删除操作的实现。
3. 插入操作的算法描述在单链表中进行插入操作时,我们需要考虑插入位置和插入的数据。
下面,我们分别讨论在头部、中间和尾部插入节点的算法描述。
3.1 在头部插入节点在单链表的头部插入节点是一种常见操作,可以通过以下算法描述实现:```pythondef insert_at_head(self, data):new_node = Node(data)new_node.next = self.headself.head = new_node```在上述代码中,我们首先创建一个新的节点new_node,然后将新节点的指针指向当前头结点的位置,最后将新节点设置为头结点,完成了在头部插入节点的操作。
3.2 在中间插入节点在单链表的中间位置插入节点需要先找到插入位置,然后进行插入操作。
下面是算法描述:```pythondef insert_after(self, prev_node, data):if prev_node is None:print("The given previous node must be in the linked list")returnnew_node = Node(data)new_node.next = prev_node.nextprev_node.next = new_node```在上述代码中,我们首先检查给定的前一个节点prev_node是否存在,然后创建一个新的节点new_node,并将新节点的指针指向prev_node的下一个节点,最后将prev_node的指针指向新节点,完成了在中间插入节点的操作。
单链表基本操作的实现单链表是一种常见的数据结构,它由多个节点组合而成,每个节点包含一个数据元素和一个指向下一个节点的指针。
通过指针,我们可以方便地在单链表中进行插入、删除和遍历等操作。
以下是关于单链表基本操作的实现。
1. 单链表的创建单链表的创建需要定义一个空的头结点,它的作用是方便在链表的头部进行添加和删除节点操作。
一个空的头节点可以在链表初始化的过程中进行创建。
```typedef struct Node{int data;struct Node *next;}Node;Node *createList(){Node *head = (Node*)malloc(sizeof(Node)); //创建空的头节点head->next = NULL;return head; //返回头节点的地址}```2. 单链表的插入单链表的插入可以分为在链表头部插入、在链表尾部插入和在链表中间插入三种情况。
a. 在链表头部插入节点:```void insertAtHead(Node *head, int data){Node *node = (Node*)malloc(sizeof(Node));node->data = data;node->next = head->next;head->next = node;}```b. 在链表尾部插入节点:```void insertAtTail(Node *head, int data){Node *node = (Node*)malloc(sizeof(Node));node->data = data;node->next = NULL;Node *p = head;while(p->next != NULL){p = p->next;}p->next = node;}```c. 在链表中间插入节点:```void insertAtMid(Node *head, int data, int pos){ Node *node = (Node*)malloc(sizeof(Node)); node->data = data;node->next = NULL;Node *p = head;int count = 0;while(p->next != NULL && count < pos-1){ p = p->next;count++;}if(count == pos-1){node->next = p->next;p->next = node;}else{printf("插入位置错误!");}}```3. 单链表的删除单链表的删除可以分为在链表头部删除、在链表尾部删除和在链表中间删除三种情况。
c语⾔数据结构之单链表的插⼊和删除操作1,定义⼀个单链表基础定义先了解⼀下:struct LNode{ //定义单链表结点类型ElemType data; //每个节点存放⼀个数据元素struct LNode *next; //指针指向下⼀个节点}LNode,*LinkList;/*struct LNode *p=(struct LNode*)malloc(sizeof(struct LNode)); //增加⼀个新的结点,在内存中申请⼀个结点所需的空间,并⽤指针p 指向这个结点*/LNode *GetElem(LinkList L,int i){int j=1;LNode *p=L->next;if(i==0)return L;if(i<1)return NULL;while(p!=NULL&&j<i){p=p->next;j++;}return p;}上述代码*LNode GetElem(LinkList L,int i)中需要注意的是:若强调这是⼀个单链表,使⽤ LinkList;若强调这是⼀个结点,则使⽤LNode *。
1,不带头结点的单链表struct LNode{ //定义单链表结点类型ElemType data; //每个节点存放⼀个数据元素struct LNode *next; //指针指向下⼀个节点}LNode,*LinkList;bool InitList(LinkList &L){ //初始化⼀个单链表L=NULL; //空表,防⽌脏数据return true;}void test(){LinkList L; //声明⼀个指向单链表的指针//初始化⼀个空表InitList(L);//.....}2,带头结点的单链表struct LNode{ //定义单链表结点类型ElemType data; //每个节点存放⼀个数据元素struct LNode *next; //指针指向下⼀个节点}LNode,*LinkList;//初始化⼀个单链表bool InitList(LinkList &L){L=(LNode *)malloc(sizeof(LNode)); //分配⼀个头结点if(L==NULL) //内存不⾜,分配失败return false;L->next=NULL; //头结点之后暂时还没有结点return true;}//判断单链表是否为空(带头结点)bool Empty(LinkList L){if(L-next==NULL)return true;elsereturn false;}void test(){LinkList L; //声明⼀个指向单链表的指针//初始化⼀个空表InitList(L);//.....2,单链表的基本操作1,插⼊1,按位序插⼊(ListInsert(&L,i,e))在第i 个位置插⼊元素e (带头结点)bool ListInsert(LinkList &L,int i,ElemType e){if(i<1)return false;LNode *p; //指针p 指向当前扫描到的节点int j=0; //当前p指向的是第⼏个结点p=L; //L指向头结点,头结点是第0 个结点(不存数据)while(p!=NULL&&j<i-1){ //循环找到第i-1个结点p=p->next;j++;}if(p==NULL) //i 值不合法return false;LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s; //将结点s 连到p 之后return true; //插⼊成功}不带头结点的:(不存在 “第0个“ 结点)实现代码如下:bool ListInsert(LinkList &L,int i,ElemType e){if(i<1)return false;if(i==1){ //插⼊第1个结点的操作与其他结点操作不同LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=L;L=s; //头指针指向新结点return true;}LNode *p; //指针p指向当前扫描到的节点int j=1; //当前p 指向的是第⼏个结点p=L; //p指向第1个结点(注意:不是头结点)while(p!=NULL&&j<i-1){ //循环找到第i-1个结点p=p->next;j++;}if(p==NULL) //i 值不合法return false;LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s; //将结点s 连到p 之后return true; //插⼊成功}2,指定结点的后插操作(InsertNextNode(LNode *p,ElemType e)在p 结点之后插⼊元素e :bool InsertNextNode(LNode *p,ElemType e){if(p==NULL)return false;LNode *s=(LNode *)malloc(sizeof(LNode));if(s==NULL) //内存分配失败return false;s->data=e; //⽤结点s保存数据元素es->next=p->next;p->next=s;}3,指定结点的前插操作在p 结点之前插⼊**元素e **:bool InsertPrioNode(LNode *p,ElemType e){if(p==NULL)return false;LNode *s=(LNode *)malloc(sizeof(LNode));if(s==NULL) //内存分配失败return false;s->next=p->next;p->next=s; //新结点s 连接到p 之后s->data=p->data; //将p 中元素复制到s 中p->data=e; //p 中元素覆盖为ereturn true;}结合下图在体会⼀下:下⾯再看⼀下在p 结点之前插⼊**结点s **:bool InsertPrioNode(LNode *p,ElemType e){if(p==NULL||s==NULL)return false;s->next=p->next;p->next=s; //s 连接到p 之后ElemType temp=p->data; //交换数据域部分p->data=s->data;s->data=temp;return true;}这招偷天换⽇结合下图好好体会⼀下:2,删除1,按位序删除(带头结点)删除表L 中第i 个位置的元素,并⽤e 返回删除元素的值。
单链表的基本操作(C语言)什么是单链表单链表(Singly Linked List)是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
每个节点只能访问其后继节点,而无法直接访问前驱节点。
单链表的特点是可以动态地插入和删除节点,相比于数组,具有更好的灵活性和扩展性。
在C语言中,我们可以使用指针来实现单链表。
单链表的基本操作1. 定义单链表结构体在C语言中,我们首先需要定义一个表示单链表的结构体。
结构体包含两个成员:数据元素和指向下一个节点的指针。
typedef struct Node {int data; // 数据元素struct Node *next; // 指向下一个节点的指针} Node;2. 创建单链表创建一个空的单链表需要进行以下步骤:•定义头节点,并初始化为NULL。
•向链表中插入新的节点。
Node* createLinkedList() {Node *head = NULL; // 头节点初始化为NULLint n; // 节点数量printf("请输入要创建的节点数量:");scanf("%d", &n);for (int i = 0; i < n; i++) {int data;printf("请输入第%d个节点的值:", i + 1);scanf("%d", &data);Node *newNode = (Node*)malloc(sizeof(Node)); // 创建新节点newNode->data = data;newNode->next = NULL;if (head == NULL) {head = newNode; // 如果是第一个节点,将其设置为头节点 } else {Node *temp = head;while (temp->next != NULL) {temp = temp->next; // 移动到链表末尾}temp->next = newNode; // 将新节点插入到链表末尾}}return head;}3. 插入节点在单链表中插入一个新的节点需要进行以下步骤:•创建一个新的节点。
C语⾔单链表的基本操作(增删改查)这是尾插法单链表,单链表⽐较适合⽤来做队列和栈,因为在链表的头和尾时的增删改查的时间复杂度为O(1),⽽在链表内部的增删改查的平均时间复杂度为O(n)。
#include "stdio.h"#include "stdlib.h"//提供malloc()和free()#include "string.h"#include "time.h"//提供strcpy(),time()等//1.⽤结构体创建链表节点//⼀个⽤来存放数据,另⼀个存放指针struct Node{int data; //数据域struct Node* next; //指针域(指向节点的指针)};//2.全局定义链表头尾指针,⽅便调⽤struct Node* head = NULL;struct Node* end = NULL;//3.向链表添加数据void AddListTill(int a ){//创建⼀个节点struct Node* temp = (struct Node*)malloc(sizeof(struct Node)); //此处注意强制类型转换//节点数据进⾏赋值temp->data = a;temp->next = NULL;//连接分两种情况1.⼀个节点都没有2.已经有节点了,添加到尾巴上if(NULL == head){head = temp;//end=temp;}else{end->next=temp;//end=temp; //尾结点应该始终指向最后⼀个}end=temp; //尾结点应该始终指向最后⼀个}//4.遍历链表并输出void ScanList(){struct Node *temp = head; //定义⼀个临时变量来指向头while (temp != NULL){printf("%d\n",temp->data);temp = temp->next; //temp指向下⼀个的地址即实现++操作}}//5.查找指定的数据是否在链表内struct Node* FindNode(int a ){struct Node *temp = head;while(temp != NULL){if(a == temp->data){return temp;}temp = temp->next;}//没找到return NULL;}//6.删除链表void FreeList(){struct Node *temp = head; //定义⼀个临时变量来指向头while (temp != NULL){struct Node* pt = temp;temp = temp->next; //temp指向下⼀个的地址即实现++操作free(pt); //释放当前}//头尾清空,不然下次的头就接着0x10head = NULL;end = NULL;}//7.在指定位置处插⼊数据void AddListRand(int index,int a){if (NULL == head){printf("链表没有节点\n");return;}struct Node* pt = FindNode(index);if(NULL == pt) //没有此节点{printf("没有指定节点\n");return;}//有此节点//创建临时节点,申请内存struct Node* temp =(struct Node *)malloc(sizeof(struct Node));//节点成员进⾏赋值temp->data = a;temp->next = NULL;//连接到链表上 1.找到的节点在尾部 2.找到的节点在中间if (pt == end){//尾巴的下⼀个指向新插⼊的节点end->next = temp;//新的尾巴end = temp;}else{//先连后⾯(先将要插⼊的节点指针指向原来找到节点的下⼀个) temp->next = pt->next;//后连前⾯pt->next = temp;}}//8.删除链表末尾数据void DeleteListTail(){if (NULL == end){printf("链表为空,⽆需删除\n");return;}//链表不为空//链表有⼀个节点if (head == end){free(head);head = NULL;end = NULL;}else{//找到尾巴前⼀个节点struct Node* temp = head;while (temp->next != end){temp = temp->next;}//找到了,删尾巴//释放尾巴free(end);//尾巴迁移end=temp;//尾巴指针为NULLend->next = NULL;}}//9.删除链表的第⼀个数据void DeleteListHead(){ //记住旧头struct Node* temp = head;//链表检测if (NULL == head){printf("链表为空\n");return;}head = head->next; //头的第⼆个节点变成新的头free(temp);}//10.删除链表指定的数据void DeleteListRand(int a){//链表判断是不是没有东西if(NULL == head){printf("链表没东西\n");return;}//链表有东西,找这个节点struct Node* temp = FindNode(a);if(NULL == temp){printf("查⽆此点\n");return;}//找到了,且只有⼀个节点if(head == end){free(head);head = NULL;end = NULL;}else if(head->next == end) //有两个节点{//看是删除头还是删除尾if(end == temp){DeleteListTail();}else if(temp == head){DeleteListHead();}}else//多个节点{//看是删除头还是删除尾if(end == temp)DeleteListTail();else if(temp == head)DeleteListHead();else//删除中间某个节点{ //找要删除temp前⼀个,遍历struct Node* pt = head;while(pt->next != temp){pt=pt->next;}//找到了//让前⼀个直接连接后⼀个跳过指定的即可 pt->next = temp->next;free(temp);}}}//主函数void main(){struct Node *pFind;srand((unsigned)time(NULL));int i;//创建20个节点for(i = 0; i < 20; i++)AddListTill(i); //添加数据//AddListTill(rand());AddListRand(4,86); //在指定位置4增加节点14//DeleteListHead(); //删除⼀个头结点//DeleteListTail(); //删除⼀个尾结点DeleteListRand(4); //删除4节点ScanList(); //遍历输出链表//FreeList(); //删除链表pFind = FindNode(5); //查找5节点if (pFind != NULL){printf("找到%d\n",pFind->data); //找到节点并且输出该节点数据 }else{printf("No Find!\n");}}以下是排序算法的时间和空间复杂度表:。
如何实现单链表的插⼊和删除操作单链表插⼊:(1)找到位置p(a i-1)(2)⽣成新结点s,数据域赋值(3)新结点指针域指向ai(ai的地址存放在a i-1的指针域)(4)a i-1的指针域指向新结点s直接上代码:Status InsertList(LinkList head,DataType x,int i){ListNode* p;p=head;int j=1;while(p && j<i){p=p->next;j++;} //p现在是a i-1这个结点if(!p || j>i){printf("Position Error!");return ERROR;}ListNode* s=(ListNode*)malloc(sizeof(ListNode));s->data=x;s->next=p->nextp->next=s;return OK;}删除单链表结点:(1)找到要删除的结点前⼀个结点p(原因是删除结点的位置在前⼀个结点的指针域)(2)把p->next指向ai的下⼀个结点(把ai从链上摘除)(3)释放ai空间直接粗暴上代码:Status DeleteList(LinkList head,int i){ListNode* p,*r; //声明两个指针,⼀个⽤来找到删除结点前的结点。
⼀个⽤来存储要删除结点的后继结点的地址的。
p=head;int j=1;while(p->next && j<i) //这⾥要判断p->next得是真(也就是说得有后继结点也就是要删除的结点)。
//不要忘了这个⽅式 p=p->next; 指针在移动 {p=p->next;j++;}if(p->next ==NULL || j>i){printf("Position Error!");return ERROR;}r=p->next; //把删除结点的⾸地址给临时结点这样就能把删除结点的指针域保存下来p->next=r->next; //删除结点的指针域指向删除结点后继结点的⾸地址free(r); //记得释放资源retuen OK;}删除结点必须保证在连边长度内。
C++实现单链表(创建、插⼊、删除)#include <iostream>#include<cstdlib>using namespace std;enum operation{create_List=1,print_List,insert_Node,delete_Node,delete_List,quit};//枚举类型,⽤于菜单选择结果struct node //结点结构{ int data ;node * next;};operation Menu(); //菜单函数node * CreateList( ); //建⽴链表函数声明void PrintList( node *); //输出链表中结点信息函数声明node * InsertNode(node *,node *); //在链表中插⼊结点函数声明node * DeleteNode(node *,int); //在链表中删除结点函数声明node * deleteList(node *head); //删除整个链表void Create(); //对应操作菜单--创建链表的操作void Print( ); //对应操作菜单--遍历链表的操作void Insert( ); //对应操作菜单--插⼊链表结点的操作void Delete( ); //对应操作菜单--删除链表结点的操作void DeleteAll(); //对应操作菜单--删除整个链表的操作int n=0; //全局整型变量存放链表中结点个数node * head=NULL ; //全局指针变量存放链表头结点地址-头指针int main(){operation menu_choice; //存放菜单选择项do//循环现实直到⽤户退出程序{menu_choice=Menu(); //菜单显⽰及⽤户选择switch(menu_choice) //⽤户选择功能匹配{case create_List: system("cls");cout<<"1 创建链表"<<endl<<endl;Create( );break;case print_List: system("cls");cout<<"2 遍历链表"<<endl<<endl;Print();break;case insert_Node: system("cls");cout<<"3 插⼊链表结点"<<endl<<endl;Insert();break;case delete_Node: system("cls");cout<<"4 删除链表结点"<<endl<<endl;Delete();break;case delete_List: system("cls");cout<<"5 删除整个链表"<<endl<<endl;DeleteAll();break;case quit :default: cout<<"退出链表操作,结束程序"<<endl;return0;}}while(menu_choice!=quit);return0;}/*创建链表*/node * CreateList( ) //建⽴链表函数{ node * s, * p ; // s指向新结点,p指向链表中最后的结点s = new node ; //动态建⽴第⼀个新结点cout<<"请输⼊⼀个整数值作为新结点的数据信息,输⼊0时建⽴链表结束"<<endl;cout<<"第"<<n+1<<"个结点"<<endl;cin >> s->data ; //输⼊新结点数据head = NULL ; //头指针初始值为NULLif( s->data==0) //第⼀个结点数据就为0,建⽴⼀个空链表{cout<<"您建⽴的空链表"<<endl;delete s ; //释放数据为0的结点}else//建⽴⾮空链表{while ( s->data != 0 ) //通过判断新结点数据来进⾏循环{ if ( head == NULL ) head = s ; //头指针赋值else p->next = s ; //将新结点插⼊已有链表的最后p = s ; // p指向链表中最后的结点n=n+1;//结点个数增1s = new node ; //动态建⽴⼀个新结点cout<<"请输⼊⼀个整数值作为新结点的数据信息,输⼊0时建⽴链表结束"<<endl;cout<<"第"<<n+1<<"个结点"<<endl;cin >> s->data ; //输⼊新结点数据}p -> next = NULL ; //设置链表尾部为空delete s ; //释放数据为0的结点cout<<endl<<"链表建⽴完成...";cout<<"建⽴的链表中共有"<<n<<"个节点"<<endl<<endl;}return ( head ) ; //返回头指针}/*遍历链表*/void PrintList( node * head) //输出链表中结点信息函数,链表遍历{ node *p=head;int i=1;cout<<endl<<"遍历链表..."<<endl;if (head!=NULL) //如果链表⾮空,即链表中有结点do//循环输出接点数据,直到移动到链表尾,即最后⼀个结点{ cout<<"第"<<i++<<"个结点数据为:"<<p->data<<endl;p=p->next;}while(p!=NULL) ;else{cout<<"链表是空链表!"<<endl;}cout<<"链表中共有"<<n<<"个节点"<<endl;}/*插⼊结点*/node * InsertNode(node *head,node * s) //插⼊结点的函数,head为链表头指针,s指向要插⼊的新结点{node *p,*q;p=head; //使p指向链表中的第⼀个结点if(head==NULL) //原来的链表是空表{ head=s; //使head指向的新结点作为头结点s->next=NULL;}else//原来的链表不是空表{while((s->data>p->data) && (p->next!=NULL)) //⽤循环定位要插⼊的结点位置p,使s插⼊到p之前的位置 {q=p; //q记录下当前的p,即q指向p的前⼀个结点p=p->next; //p后移⼀个结点}if(s->data<=p->data) //要插⼊的结点数据⽐最后⼀个结点数据⼩{ if(head==p) //判断是否插⼊链表中的第⼀个结点之前{ head=s; //插到原来第⼀个结点之前s->next=p;}else//插到q指向的结点之后,p指向的结点之前{ q->next=s;s->next=p;}}else//要插⼊的结点数据⽐最后⼀个结点数据还⼤{ p->next=s; // 插到链表最后的结点之后,作为链表的尾结点s->next=NULL;}}n=n+1; //结点数加1cout<<"成功完成⼀个新结点插⼊..."<<endl;return (head);}/*删除结点*/node *DeleteNode(node *head,int delData) //删除数据为delDate的结点的函数{node *p,*q;p=head; //使p指向第⼀个结点if (head==NULL) //是空表{ cout<<"该链表是空链表,不能进⾏结点删除!"<<endl;return(head);}//先找到要删除的结点while(delData!=p->data && p->next!=NULL) //p指向的不是所要找的结点且后⾯还有结点{ q=p; //q⽤来记录p前⼀个结点p=p->next;} //p后移⼀个结点if(delData==p->data) //找到了要删除的结点{ if(p==head) //如果要删除的是头结点head=p->next; //若p指向的是⾸结点,把第⼆个结点地址赋予headelse q->next=p->next; //否则将下⼀结点地址赋给前⼀结点地址cout<<"成功删除数据为"<<delData<<"的结点"<<endl;n=n-1;}elsecout<<"要删除的数据为"<<delData<<"的结点在链表中没有找到"<<endl; //找不到该结点return(head);}/*删除整个链表*/node * deleteList(node *head) //删除整个链表{node *p,*s;p=head;if(head==NULL)cout<<"链表本⾝就为空链表";else{while(p->next!=NULL){s=p;p=p->next;delete s;n--;}delete p;n--;head=NULL;}cout<<"整个链表删除成功!"<<endl;return head;}/*菜单函数*/operation Menu(){ int choice;cout<<endl<<endl;cout<<"+-------------链表操作菜单---------------+"<<endl;cout<<"| |"<<endl;cout<<"| 1->创建链表 |"<<endl;cout<<"| 2->遍历链表 |"<<endl;cout<<"| 3->插⼊节点 |"<<endl;cout<<"| 4->删除节点 |"<<endl;cout<<"| 5->删除链表 |"<<endl;cout<<"| 6->退出 |"<<endl;cout<<"| |"<<endl;cout<<"+----------------------------------------+"<<endl;cout<<endl<<endl<<"请输⼊功能序号";cin>>choice;return operation(choice);}/*对应操作菜单--创建链表的操作*/void Create(){if(head==NULL) //如果链表中已有结点,不允许重新建⽴{head=CreateList( );}else{cout<<"已创建过链表,不允许再次创建"<<endl;cout<<"如果想重新创建,先删除原先链表"<<endl;}}/*对应操作菜单--遍历链表的操作*/void Print( ){PrintList(head);}/*对应操作菜单--插⼊链表结点的操作*/void Insert( ){char IsGo; //是否继续操作标志IsGo='y';cout<<endl<<"开始进⾏结点插⼊操作"<<endl;node *stu;while(IsGo=='y'||IsGo=='Y'){ stu=new node; //创建要插⼊的新结点cout<<endl<<"输⼊要插⼊的新结点数据:";cin>>stu->data; //输⼊要插⼊的新结点数据head=InsertNode(head,stu); //调⽤插⼊函数,返回链表头指针cout<<"是否继续插⼊新结点? (继续插⼊请按y或Y,退出请按其它键)"; cin>>IsGo;}cout<<endl<<"结点插⼊操作结束"<<endl;}/*对应操作菜单--删除链表结点的操作*/void Delete( ){char IsGo; //是否继续操作标志int del_num; //要删除的结点的数据IsGo='y';cout<<endl<<"开始进⾏结点插⼊操作"<<endl;while(IsGo=='y'||IsGo=='Y'){cout<<endl<<"输⼊要删除的节点的数据:"; //输⼊要插⼊的结点cin>>del_num; //输⼊要删除的结点的数据head=DeleteNode(head,del_num); //删除后链表的头地址cout<<"是否继续删除结点? (继续插⼊请按y或Y,退出请按其它键)"; cin>>IsGo;}cout<<endl<<"结点删除操作结束"<<endl;}/*对应操作菜单--删除整个链表的操作*/void DeleteAll(){head=deleteList(head);}。
单链表(建⽴、插⼊、删除、打印)单向链表创建链表是动态分配存储空间的链式存储结构。
其包括⼀个“头指针”变量,其中第0个结点称为整个链表的头结点,头结点中存放⼀个地址,该地址指向⼀个元素,头结点⼀般不存放具体数据,只是存放第⼀个结点的地址。
链表中每⼀个元素称为“结点”,每个结点都由两部分组成:存放数据元素的数据域和存储直接后继存储位置的指针域。
指针域中存储的即是链表的下⼀个结点存储位置,是⼀个指针。
多个结点链接成⼀个链表。
最后⼀个结点的指针域设置为空(NULL),作为链表的结束标志,表⽰它没有后继结点。
使⽤结构体变量作为链表中的结点,因为结构体变量成员可以是数值类型,字符类型,数组类型,也可以是指针类型,这样就可以使⽤指针类型成员来存放下⼀个结点的地址,使其它类型成员存放数据信息。
当⼀个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。
单链表的⽰意图如下:Head指针为单链表的头指针,单链表L:L既是单链表的名字,也是其头指针。
链表中的最后⼀个结点的指针域定义为空指针(NULL)。
在创建列表时要动态为链表分配空间,C语⾔的库函数提供了⼏种函数实现动态开辟存储单元。
malloc()函数实现动态开辟存储单元:malloc函数原型为:void *malloc(unsigned int size);其作⽤是在内存的动态存储区中分配⼀个长度为size的连续空间,函数返回值是⼀个指向分配域起始地址的指针(类型为void)。
如果分配空间失败(如,内存空间不⾜),则返回空间指针(NULL)1.单链表的初始化,即建⽴⼀个空链表。
//不带头结点的单链表的初始化void LinkedListInit1(LinkedList L){L=NULL;}//带头结点的单链表的初始化void LinkedListInit2(LinkedList L){L=(LNode *)malloc(sizeof(LNode));if(L==NULL){printf("申请空间失败!");exit(0);}L->next=NULL;}2.单链表的求表长操作单链表的求表长操作需要设定当前指针p和⼀个计数器j,初始时p指向链表中的第⼀个结点,p每向下移动⼀个结点时,j就加1,直到到达p 链表的尾部。
单链表的基本操作
#include <stdio.h>
#include <stdlib.h>
typedef char date;
typedef struct node
{
date ch;
struct node *next;
}list;
typedef list *linklist;
linklist creat()
{
date ch;
linklist head=(linklist)malloc(sizeof(list));
list *p,*r;
r=head;
ch=getchar();
while(ch!='\n')
{
p=(linklist)malloc(sizeof(list));
p->ch=ch;
r->next=p;
r=p;
ch=getchar();
}
r->next=NULL;
return (head);
}
void insert(linklist head,int i,char x)
{
int j=0;
linklist r,p;
p=head->next;
while(p&&j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1)
exit(1);
r=(linklist)malloc(sizeof(list));
r->ch=x;
r->next=p->next;
p->next=r;
}
void puter(linklist linker)
{
linklist p;
p=linker->next;
while(p!=NULL)
{
printf("%c ",p->ch);
p=p->next;
}
}
void delet(linklist head ,int i)
{
int j=0;
linklist r,p;
p=head->next;
while(p&&j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1)
exit(1);
r=p->next;
p->next=r->next;
free(r);
}
int main()
{
static int q,k;
char w;
printf("请输入字符穿,并以ENTER键结束\n");
linklist head,p,linker=creat();
puter(linker);
printf("请输入插入位置和插入字母\n");
scanf("%d %c",&q,&w);
insert(linker,q,w);
puter(linker);
printf("\n请输入删除位置的序号:\n");
scanf("%d",&k);
delet(linker,k);
puter(linker);
printf("\n");
return 0;
}。