单链表增删改查

合集下载

单链表的增删查改功能

单链表的增删查改功能

单链表的增删查改功能的实现#include<iostream>using namespace std;class LinkNode{friend class List;private:int date;LinkNode *link;LinkNode(const int& d=int()):date(d),link(NULL) {} };class List{public:void CreatList(int );bool Insert(int i,int& x);bool Remove(int i,int& x);void PrintList();int Find(const int& date);int FindPos(int pos);void Update(const int &e,const int &ne);void Showmeun();private:LinkNode *first;};void List::CreatList(int n){LinkNode *p,*q;first=new LinkNode;first->link=NULL;p=first;for(int i=0;i<n;i++){cout<<"请输入第"<<i+1<<"个数: ";q=new LinkNode;cin>>q->date;q->link=p->link;p->link=q;p=q;}}bool List::Insert(int i, int &x){if(first==NULL||i==0){LinkNode *newNode=new LinkNode(x);if(newNode==NULL){cerr<<"存储分配错误!"<<endl;exit(i);}newNode->link=first;first=newNode;}else{LinkNode *p=first;for(int k=1;k<i;k++)if(p==NULL)break;elsep=p->link;if(p==NULL){cerr<<"无效的插入位置!"<<endl;return false;}else{LinkNode *newNode=new LinkNode(x);if(newNode==NULL){cerr<<"存储分配错误!"<<endl;exit(1);}newNode->link=p->link;p->link=newNode;}}return true;}bool List::Remove(int i, int &x){LinkNode *del,*p;if(i<=1){del=first;first=first->link;}else{p=first;for(int k=1;k<i;k++)if(p==NULL)break;elsep=p->link;if(p==NULL||p->link==NULL){cerr<<"无效的删除位置!"<<endl;return false;}del=p->link;p->link=del->link;}x=del->date;delete del;return true;};void List::Showmeun(){cout<<"********链表的增删查改功能*********"<<endl;cout<<" 1-链表全部数据的输出"<<endl;cout<<" 2-链表插入元素"<<endl;cout<<" 3-链表删除元素"<<endl;cout<<" 4-链表查找元素"<<endl;cout<<" 5-链表数据的修改"<<endl;cout<<" 0-退出"<<endl;cout<<"*********************************"<<endl;cout<<" 请输入功能序号:"<<endl;}void List::PrintList(){LinkNode *p;cout<<"输出单链表为:";p=first->link;while(p!=NULL){cout<<p->date<<" ";p=p->link;}cout<<endl;}int List::Find(const int &date){LinkNode *p;p=first;for(int k=0;p!=NULL;k++){if(p->date==date)return k;p=p->link;}return -1;}int List::FindPos(int pos){if(pos<1){cerr<<"位置超出范围!"<<endl;exit(1);}LinkNode* p=first;int i=-1;while(p!=NULL){i++;if(i==pos)break;p=p->link;}if(p!=NULL)returnp->date;else{cerr<<"位置超出范围!"<<endl;exit(1);}return -1;}void List::Update(const int &e,const int &ne){LinkNode *p = first;LinkNode *q = first;while(p != NULL && p->link != NULL){q = p->link;if(e == q->date){q->date = ne;continue;}p = p->link;}}void main(){List link;int n,choice,i,x,y;cout<<"请输入链表中元素的个数,建立链表:"<<endl;cin>>n;link.CreatList(n);link.Showmeun();cin>>choice;while(choice!=0){switch(choice){case 1:link.PrintList();break;case 2:cout<<"请输入你要插入元素的位置:"<<endl;cin>>i;cout<<"请输入你要插入元素的值:"<<endl;cin>>x;link.Insert(i,x);break;case 3:cout<<"请输入你要删除元素的位置:"<<endl;cin>>i;link.Remove(i,x);break;case 4:cout<<"******************"<<endl;cout<<"1-按元素的数值查找"<<endl;cout<<"2-按元素的位置查找"<<endl;cout<<"******************"<<endl;cout<<"请选择:"<<endl;cin>>x;if(x==1){cout<<"请输入要查找的数据:"<<endl;cin>>x;i=link.Find(x);if(i!=-1)cout<<"在第"<<i<<"个位置找到数据:"<<x<<endl;elsecout<<"没有找到数据!"<<endl;}else{cout<<"请输入需要查找元素位置"<<endl;cin>>i;x=link.FindPos(i);cout<<"第"<<i<<"个位置的数据为:"<<x<<endl;}break;case 5:cout<<"请输入原数据和更改后的数据:"<<endl;cin>>x>>y;link.Update(x,y);cout<<"你已经成功的将"<<x<<"改成了"<<y<<"!"<<endl;break;}cout<<"请输入功能序号:"<<endl;cin>>choice;}}。

C语言单向链表的增删查改快速掌握

C语言单向链表的增删查改快速掌握

C 语⾔单向链表的增删查改快速掌握⽬录前⾔⼀、创建⼆、单向链表的函数声明三、函数实现1.创建节点2.尾插节点3.头插4.尾删5.头删6.查找节点7.修改总结前⾔链表是线性表的链式存储结构,它可以以O(1)的时间复杂度进⾏插⼊或者删除,同时由于是链式结构相⽐顺序表⽽⾔,不会存在空间浪费的情况。

⽽链表⼜分为带头单向链表,不带头单向链表,带头循环链表,不带头循环链表,带头双向循环链表,不带头双向循环链表,带头双向链表,不带头双向链表,总共有⼋种,其中结构最简单的是不带头单向链表,也是实现起来最容易出错的。

并且我们在⽹上进⾏链表的oj 时,题⽬基本也是不带头的单向链表,⽽且也是互联⽹⼤⼚⾯试中最容易考的。

⼀、创建123456typedef int SLTDadaType;//存放的数据类型struct SListNode { SLTDadaType _data;//存放的数据struct SListNode* _next;//指向下⼀个节点的指针};typedef struct SListNode SListNode;⼆、单向链表的函数声明123456SListNode* BuyListNode(SLTDadaType x);//创建⼀个节点SListNode* SListPushBack(SListNode* head, SLTDadaType x);//尾插SListNode* SListPopBack(SListNode* head);//头插SListNode* SListPushFornt(SListNode* head, SLTDadaType x);//尾删SListNode* SListPopFornt(SListNode* head);//头删SListNode* SListFind(SListNode* head, SLTDadaType x);//查找⼀个节点void SListModify(SListNode* head, SLTDadaType x,SLTDadaType y);//x 修改三、函数实现1.创建节点1234SListNode* BuyListNode(SLTDadaType x){ SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));newnode->_data = x;56newnode->_next = NULL;return newnode;}2.尾插节点12345678910111213141516171819SListNode* SListPushBack(SListNode* head, SLTDadaType x){SListNode* newnode = BuyListNode(x);//⽆论节点是否为空,都先进⾏创建⼀个节点if (head == NULL) //头节点为空{head = newnode; return head; } else //头节点不为空,直接遍历到链表结尾进⾏尾插 {SListNode* tail = head;while (tail->_next != NULL){tail = tail->_next; } tail->_next = newnode;return head;}}3.头插123456SListNode* SListPushFornt(SListNode* head, SLTDadaType x){ SListNode* newnode = BuyListNode(x);newnode->_next = head;head = newnode;return head;}4.尾删12345678*********SListNode* SListPopBack(SListNode* head){//1.空//2.只有⼀个节点 //3.有多个节点 if (head == NULL) { return head; }else if (head->_next== NULL){free(head);head = NULL;14151617181920212223242526272829return head;}else{ SListNode* prev = NULL; SListNode* tail = head;while (tail->_next != NULL) //利⽤前指针来保存要删除的节点的前⼀个节点{prev = tail;tail = tail->_next; } free(tail); if (prev != NULL)prev->_next = NULL;return head;}}5.头删1234567891011121314SListNode* SListPopFornt(SListNode* head){if (head == NULL){ return head; } else {SListNode* cur = head->_next;free(head); head = cur; return head; }}6.查找节点12345678910111213141516SListNode* SListFind(SListNode* head, SLTDadaType x){SListNode* cur = head; while (cur) { if (cur->_data == x) { return cur; }else{cur = cur->_next; } }return NULL;}7.修改1234567891011void SListModify(SListNode* head, SLTDadaType x, SLTDadaType y)//x 修改{SListNode* find = SListFind(head, x); if (find) { find->_data = y; }else{printf("对不起,您要修改的值不存在\n"); }}总结本篇⽂章主要是针对单向链表⼀些基本操作的代码实现,若有写的错误或值得改进的地⽅,请⼤家多多留⾔指出。

单链表 头指针 尾指针 删除指定节点的方法

单链表 头指针 尾指针 删除指定节点的方法

单链表的头指针和尾指针是单链表中非常重要的概念,它们分别指向链表的第一个节点和最后一个节点。

删除指定节点也是单链表中常见的操作之一。

本文将介绍单链表的头指针、尾指针以及删除指定节点的相关方法。

一、单链表简介单链表是由节点构成的链式结构,每个节点包括数据域和指针域。

数据域存储节点的数据,指针域指向下一个节点。

单链表中的第一个节点被称为头节点,最后一个节点的指针域为NULL。

二、头指针和尾指针1. 头指针头指针是指向链表中第一个节点的指针,它的作用是方便对链表的操作。

通过头指针可以找到链表的第一个节点,从而对链表进行遍历或其他操作。

2. 尾指针尾指针是指向链表中最后一个节点的指针,它的作用是快速定位链表的尾部。

通过尾指针可以直接找到链表的最后一个节点,而不需要遍历整个链表。

三、删除指定节点的方法单链表中的节点删除操作是常见而重要的操作,通过删除指定节点可以对链表进行精确的控制。

1. 删除指定节点的基本思路要删除单链表中的指定节点,需要找到待删除节点的前一个节点,然后修改指针域将其指向待删除节点的下一个节点。

具体步骤如下:- 遍历链表,找到待删除节点的前一个节点prev;- 将待删除节点的指针域赋值给prev的指针域,跳过待删除节点;- 释放待删除节点的内存空间。

2. 删除指定节点的实现实现删除指定节点的方法可以通过编程语言来完成。

下面以C语言为例,给出删除指定节点的代码示例:```cvoid deleteNode(Node* head, int value){Node* prev = head;Node* cur = head->next;while (cur != NULL){if (cur->data == value){prev->next = cur->next;free(cur);return;}prev = cur;cur = cur->next;}}```以上代码中,首先定义了两个指针prev和cur,分别指向头节点和下一个节点。

C语言单链表的基本操作(增删改查)

C语言单链表的基本操作(增删改查)

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");}}以下是排序算法的时间和空间复杂度表:。

单链表应用实例及代码实现

单链表应用实例及代码实现

单链表应⽤实例及代码实现问题:使⽤带 head 头的单向链表实现 –英雄列表管理完成对英雄⼈物的增删改查操作。

⾸先准备⼀个hero类:1. class hero {2. private int num;//序号(排名)3. private String name;//名称4. private String nikname;//别名5. private hero next;//指向下⼀个6.7. public hero(int num, String name, String nikname) { ... } //构造器8.9. public int getNum() { ... }10. public void setNum(int num) { ... }11. public String getName() { ... }12. public void setName(String name) { ... }13. public String getNikname() { ... }14. public void setNikname(String nikname) { ... }15. public hero getNext() { ... }16. public void setNext(hero next) { ... }17.18. @Override19. public String toString() { ... } //为了显⽰⽅便显⽰重写tostring20. }1) 第⼀种⽅法:在添加英雄时,直接添加到链表的尾部(add())思路分析: 添加(创建) 1、先创建⼀个head头节点(①不存放具体数据,②作⽤就是表⽰单链表头next)private hero head = new hero(-1, "", ""); //先初始化⼀个头节点,头节点不能动,不存放具体数据 2、之后我们每添加⼀个节点,就直接加⼊到链表的最后 遍历 1、通过⼀个辅助变量遍历,帮助遍历整个链表2) 第⼆种⽅式在添加英雄时,根据排名将英雄插⼊到指定位置(如果有这个排名,则添加失败,并给出提⽰) 思路分析: 1、⾸先找到新添加的节点的位置,是通过辅助变量,通过遍历来搞定 2、新的节点.next=temp.next (temp为插⼊后的新节点的前⼀个节点) 3、将temp.next=新的节点3) 修改节点 思路分析: 1、先找到该节点,通过遍历 2、 = ; temp.nickname= newHero.nickname;4) 删除节点(delete()) 思路分析: 1、先找到需要删除的这个节点的前⼀个节点temp 2、 temp.next=temp.next.next 3、删除的节点,将不会有其他引⽤,会被GC掉单链表代码实现:1. public class singlelinkedlist {2. //先初始化⼀个头节点,头节点不能动,不存放具体数据3. private hero head = new hero(-1, "", "");4.5. //添加节点到单向链表6. /**7. * 思路:当不考虑标编号顺序时8. * 1、找到当前链表的最后节点9. * 2、将最后这个节点的next指向新的节点10. */11. public void add(hero h) {12. //因为head节点不能动,因此我们需要⼀个辅助变量temp13. hero temp = head;14. //遍历链表,找到最后⼀个节点15. while (true) {16. if (temp.getNext() == null) {17. break;19. //如果没有到最后,将temp后移20. temp = temp.getNext();21. }22. //当退出while循环时,temp就指向了链表的最后23. //将最后这个节点的next指向新的节点24. temp.setNext(h);25. }26.27. //第⼆种⽅式在添加英雄时,根据排名将英雄插⼊到指定位置28. //(如果有这个排名,则添加失败,并给出提⽰)29. public void addByOrder(hero h) {30. //因为头节点不能动,因此我们仍然通过⼀个辅助指针(变量)来帮助找到添加的位置31. //因为单链表,因为我们找的temp是位于添加位置的前⼀个节点,否则插⼊不了32. hero temp = head;33. boolean flag = false;// flag 标志添加的编号是否存在,默认为 false34. while (true) {35. if (temp.getNext() == null) {//说明 temp 已经在链表的最后36. break;37. } else if (temp.getNext().getNum() > h.getNum()) {//位置找到,就在 temp 的后⾯插⼊38. break;39. } else if (temp.getNext().getNum() == h.getNum()) {//说明希望添加的 heroNode 的编号已然存在40. flag = true;41. break;42. }43. temp = temp.getNext();//后移,遍历当前链表44. }45. if (flag) { //不能添加,说明编号存在46. System.out.println("添加的序号为" + h.getNum() + "的英雄序号已经存在,添加失败。

【算法与数据结构】单链表的增删改查、逆序打印与输出、合并有序链表

【算法与数据结构】单链表的增删改查、逆序打印与输出、合并有序链表

【算法与数据结构】单链表的增删改查、逆序打印与输出、合并有序链表最近博主在B站学习算法与数据结构,视频链接:这是⼀道课后练习,题⽬是:合并两个有序的单链表,使合并后的链表依然有序。

代码如下,合并部分的代码是mergeTwoSingleLinkedList:1import java.util.Stack;23public class SingleLinkedListDemo{45public static void main(String[] args){6boolean flag = false; // true=直接添加7 HeroNode player1 = new HeroNode(23,"詹姆斯","King");8 HeroNode player2 = new HeroNode(24,"科⽐","⿊曼巴");9 HeroNode player3 = new HeroNode(2,"韦德","闪电侠");10 HeroNode player4 = new HeroNode(3,"戴维斯","浓眉");1112 HeroNode newPlayer1 = new HeroNode(14,"丹尼格林","皇阿玛");13 HeroNode newPlayer2 = new HeroNode(32,"麦基","囧哥");14 HeroNode newPlayer3 = new HeroNode(34,"阿德托昆博","字母哥");15 HeroNode newPlayer4 = new HeroNode(0,"维斯布鲁克","神龟");16 SingleLinkedList singleLinkedList = new SingleLinkedList();17 SingleLinkedList newsingleLinkedList = new SingleLinkedList();18if (flag) {19 singleLinkedList.add(player1);20 singleLinkedList.add(player2);21 singleLinkedList.add(player3);22 singleLinkedList.add(player4);23 System.out.println("直接添加后的链表情况:");24 singleLinkedList.list();25 System.out.println("\n");26 }else {27 singleLinkedList.addByOrder(player1);28 singleLinkedList.addByOrder(player2);29 singleLinkedList.addByOrder(player3);30 singleLinkedList.addByOrder(player4);31 System.out.println("链表1排序后的链表情况:");32 singleLinkedList.list();33 newsingleLinkedList.addByOrder(newPlayer1);34 newsingleLinkedList.addByOrder(newPlayer2);35 newsingleLinkedList.addByOrder(newPlayer3);36 newsingleLinkedList.addByOrder(newPlayer4);37 System.out.println("链表2排序后的链表情况:");38 newsingleLinkedList.list();39 }40//merge two singleLinkedList41 System.out.println("合并两个有序链表并返回⼀个有序链接:");42 mergeTwoSingleLinkedList(singleLinkedList.getHead(),newsingleLinkedList.getHead());43 singleLinkedList.list();44 System.out.println("***************----------------***************");45//update46 HeroNode newPlayer = new HeroNode(2,"欧⽂","⼩王爷");47 singleLinkedList.update(newPlayer);48 System.out.println("修改后的链表情况:");49 singleLinkedList.list();50//delete51 singleLinkedList.del(24);52 System.out.println("删除后的链表情况:");53 singleLinkedList.list();54//查找倒数第k个节点55 HeroNode res = findLastIndexNode(singleLinkedList.getHead(),2);56 System.out.println("倒数第k个节点res="+ res);57//求单链表有效节点的个数58 System.out.println("有效的节点个数="+getLength(singleLinkedList.getHead()));59//逆序打印单链表,不改变链表结构60 System.out.println("逆序打印单链表,不改变单链表的结构");61 reversePrint(singleLinkedList.getHead());62 System.out.println("原链表如下:");63 singleLinkedList.list();64//反转单链表65 System.out.println("反转单链表");66 reverseList(singleLinkedList.getHead());67 singleLinkedList.list();68 }6972return;//若其中1个链表为空,不进⾏合并73 }74 HeroNode temp = head1; // 指向head1链表的头节点75 HeroNode cur2 = head2.next; // 指向head2链表头节点的下⼀个节点76 HeroNode next1 = null; //保存temp的下⼀个节点77 HeroNode next2 = null; //保存cu2的下⼀个节点78while(cur2 != null){79 next2 = cur2.next;80while (temp.next != null){81 next1 = temp.next;82if (cur2.no <= temp.next.no){ //当cur2的no⼩于等于temp下⼀个节点的no时83 cur2.next = temp.next; // 将cur2插⼊到head1中84 temp.next = cur2;85break;86 }else {87 temp = next1; //将链表head1向后移,遍历head188if(temp.next == null){// head1到最后时,将cur2添加到head1的末尾89 temp.next = cur2;90 cur2.next = null;91break;92 }93 }94 }95 cur2 = next2; //将head2向后移,重新遍历head1的整个链表96 }97 }98public static void reversePrint(HeroNode head){99if (head.next == null){100return;101 }102 Stack<HeroNode> stack = new Stack<HeroNode>();103 HeroNode cur = head.next;104while (cur != null){105 stack.push(cur);106 cur = cur.next;107 }108while (stack.size()>0){109 System.out.println(stack.pop());110 }111 }112public static void reverseList(HeroNode head){113if (head.next == null || head.next.next == null){114return;115 }116 HeroNode cur = head.next;117 HeroNode next = null;118 HeroNode reverseHead = new HeroNode(0,"","");119while (cur != null){120 next = cur.next;121 cur.next = reverseHead.next;122 reverseHead.next = cur;123 cur = next;124 }125 head.next = reverseHead.next;126 }127128public static HeroNode findLastIndexNode(HeroNode head, int index){129if(head.next == null){130return null;131 }132int size = getLength(head);133if(index <=0 || index > size){134return null;135 }136 HeroNode cur = head.next;137for (int i=0;i<size-index;i++){138 cur = cur.next;139 }140return cur;141142 }143public static int getLength(HeroNode head){144if(head.next == null){145return 0;146 }147int length = 0;148 HeroNode cur = head.next;149while (cur != null){150 length++;151 cur = cur.next;152 }153return length;157class SingleLinkedList{158private HeroNode head = new HeroNode(0, "", "");159public HeroNode getHead(){return head;}160161public void add(HeroNode heroNode){162 HeroNode temp = head;163while(true){164if(temp.next == null){165break;166 }167 temp = temp.next;168 }169 temp.next = heroNode;170 }171172public void addByOrder(HeroNode heroNode){173 HeroNode temp = head;174boolean flag = false;175while(true){176if(temp.next == null){177break;178 }179if(temp.next.no > heroNode.no){180break;181 }else if (temp.next.no == heroNode.no){182 flag = true;183break;184 }185 temp = temp.next;186 }187if(flag){188 System.out.printf("准备插⼊的英雄编号%d已存在,不能加⼊",heroNode.no); 189 } else {190 heroNode.next = temp.next;191 temp.next = heroNode;192 }193 }194195public void update(HeroNode newHeroNode){196if(head.next == null){197 System.out.println("链表为空");198return;199 }200 HeroNode temp = head.next;201boolean flag = false;202while (true){203if (temp == null){204break;205 }206if(temp.no == newHeroNode.no){207 flag = true;208break;209 }210 temp = temp.next;211 }212if (flag){213 = ;214 temp.nickname = newHeroNode.nickname;215 }else {216 System.out.printf("没有找到编号%d的节点,不能修改\n", newHeroNode.no); 217 }218 }219220public void del(int no){221 HeroNode temp = head;222boolean flag = false;223while (true){224if (temp.next == null){225 System.out.println("已遍历完整个链表\n");226break;227 }228if (no == temp.next.no){229 flag = true;230break;231 }232 temp = temp.next;233 }234if(flag){235 temp.next = temp.next.next;236 }else {237 System.out.printf("要删除的节点%d不存在\n", no);241public void list(){242if (head.next == null){243 System.out.println("链表为空");244return;245 }246 HeroNode temp = head.next;247while (true){248if (temp == null){249break;250 }251 System.out.println(temp);252 temp = temp.next;253 }254 }255 }256257class HeroNode{258public int no;259public String name;260public String nickname;261public HeroNode next;262263public HeroNode(int no, String name, String nickname){264this.no = no; = name;266this.nickname = nickname;267 }268 @Override269public String toString(){270return "HeroNode [no" + no +", name=" + name + ", nickname="+ nickname + "]"; 271 }272 }打印结果如下:1链表1排序后的链表情况:2 HeroNode [no2, name=韦德, nickname=闪电侠]3 HeroNode [no3, name=戴维斯, nickname=浓眉]4 HeroNode [no23, name=詹姆斯, nickname=King]5 HeroNode [no24, name=科⽐, nickname=⿊曼巴]6链表2排序后的链表情况:7 HeroNode [no0, name=维斯布鲁克, nickname=神龟]8 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]9 HeroNode [no32, name=麦基, nickname=囧哥]10 HeroNode [no34, name=阿德托昆博, nickname=字母哥]11合并两个有序链表并返回⼀个有序链接:12 HeroNode [no0, name=维斯布鲁克, nickname=神龟]13 HeroNode [no2, name=韦德, nickname=闪电侠]14 HeroNode [no3, name=戴维斯, nickname=浓眉]15 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]16 HeroNode [no23, name=詹姆斯, nickname=King]17 HeroNode [no24, name=科⽐, nickname=⿊曼巴]18 HeroNode [no32, name=麦基, nickname=囧哥]19 HeroNode [no34, name=阿德托昆博, nickname=字母哥]20 ***************----------------***************21修改后的链表情况:22 HeroNode [no0, name=维斯布鲁克, nickname=神龟]23 HeroNode [no2, name=欧⽂, nickname=⼩王爷]24 HeroNode [no3, name=戴维斯, nickname=浓眉]25 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]26 HeroNode [no23, name=詹姆斯, nickname=King]27 HeroNode [no24, name=科⽐, nickname=⿊曼巴]28 HeroNode [no32, name=麦基, nickname=囧哥]29 HeroNode [no34, name=阿德托昆博, nickname=字母哥]30删除后的链表情况:31 HeroNode [no0, name=维斯布鲁克, nickname=神龟]32 HeroNode [no2, name=欧⽂, nickname=⼩王爷]33 HeroNode [no3, name=戴维斯, nickname=浓眉]34 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]35 HeroNode [no23, name=詹姆斯, nickname=King]36 HeroNode [no32, name=麦基, nickname=囧哥]37 HeroNode [no34, name=阿德托昆博, nickname=字母哥]38倒数第k个节点res=HeroNode [no32, name=麦基, nickname=囧哥]39有效的节点个数=740逆序打印单链表,不改变单链表的结构41 HeroNode [no34, name=阿德托昆博, nickname=字母哥]42 HeroNode [no32, name=麦基, nickname=囧哥]43 HeroNode [no23, name=詹姆斯, nickname=King]44 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]45 HeroNode [no3, name=戴维斯, nickname=浓眉]49 HeroNode [no0, name=维斯布鲁克, nickname=神龟]50 HeroNode [no2, name=欧⽂, nickname=⼩王爷]51 HeroNode [no3, name=戴维斯, nickname=浓眉]52 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]53 HeroNode [no23, name=詹姆斯, nickname=King]54 HeroNode [no32, name=麦基, nickname=囧哥]55 HeroNode [no34, name=阿德托昆博, nickname=字母哥] 56反转单链表57 HeroNode [no34, name=阿德托昆博, nickname=字母哥]58 HeroNode [no32, name=麦基, nickname=囧哥]59 HeroNode [no23, name=詹姆斯, nickname=King]60 HeroNode [no14, name=丹尼格林, nickname=皇阿玛]61 HeroNode [no3, name=戴维斯, nickname=浓眉]62 HeroNode [no2, name=欧⽂, nickname=⼩王爷]63 HeroNode [no0, name=维斯布鲁克, nickname=神龟]。

单链表的建立、插入和删除

单链表的建立、插入和删除

单链表的建立、插入和删除单链表的建立插入删除#include<stdio.h>#include<stdlib.h>/*线性表*/struct TLink {int data;struct TLink * next;};/*end struct TLink*//*生成新元素*/struct TLink * new_item(int number){struct TLink * r = 0;r = (struct TLink *)malloc(sizeof(struct TLink));r->data = number;r->next = 0;return r;}/*end new_item*//*在线性表中查询数据*/struct TLink * lookup(struct TLink * root, int number) {struct TLink * h = root;while(h) {if (h->data == number) return h;h = h->next ;}/*end lookup*/return 0;}/*在线性表中追加一个数据*/void append(struct TLink * * root, int number){struct TLink * r = 0, * n = 0;if (!root) return ;/*不记录重复元素*/if (lookup(*root, number)) return;/*如果表为空则新建表*/r = *root;if (!r) {*root = new_item(number);return ;}/*end if*//*为保证为有序线性表,如果数据比表头还小则作为表头*/ if (number < r->data ) {n = new_item(number);n->next = r;*root = n;return ;}/*end if*//*在有序线性表中查找位置插入元素*/while(r) {n = r->next ;/*如果已经是表尾则直接追加*/if (!n) {n = new_item(number);r->next = n;return ;}/*end if*//*在中央某处插入*/if (number < n->data ) {r->next = new_item(number);r->next->next = n;return ;}/*end if*/r = n;}/*end while*/}/*end append*//*打印有序线性表*/void print(struct TLink * root){struct TLink * r = root;printf("【");while(r) {printf("%d ", r->data );r = r->next ;}/*end while*/printf("\b】\n");}/*end print*//*将有序线性表h1合并至有序线性表h0,并销毁线性表h1*/ void merge(struct TLink ** h0, struct TLink ** h1){struct TLink * h = 0, * k = 0;if (!h0 || !h1) return ;h = *h1;while(h) {append(h0, h->data );k = h;h = h->next ;free(k);}/*end h*/h1 = 0;}int main(void){int i = 0; struct TLink * x=0, *y = 0;int a[] = {8,4,3,9,5,1};int b[] = {7,2,1,5,6,0};printf("原数据为:\n数组A:【");for(i = 0; i < 6; i++) {printf("%d ", a[i]);append(&x, a[i]);}/*next*/printf("\b】\n数组B:【");for(i = 0; i < 6; i++) {printf("%d ", b[i]);append(&y, b[i]);}/*next*/printf("\b】\n转换为有序线性表\nA:");print(x);printf("B:");print(y);printf("AB合并后为:");merge(&x, &y);print(x);return 0;}。

单链表插入和删除节点的代码

单链表插入和删除节点的代码

单链表插入和删除节点的代码单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

在实际应用中,我们经常需要对单链表进行插入和删除操作,以便动态地修改和管理数据。

1. 单链表的定义首先,我们需要定义一个单链表的数据结构。

在这个例子中,我们将使用C++语言来实现。

#include <iostream>// 定义单链表节点struct ListNode {int val; // 节点的值ListNode* next; // 指向下一个节点的指针// 构造函数ListNode(int x) : val(x), next(nullptr) {}};// 定义单链表类class LinkedList {private:ListNode* head; // 头指针public:LinkedList() : head(nullptr) {}// 插入节点到链表尾部void insertNode(int val) {ListNode* newNode = new ListNode(val);if (head == nullptr) {head = newNode;} else {ListNode* curr = head;while (curr->next != nullptr) {curr = curr->next;}curr->next = newNode;}}// 删除指定值的节点void deleteNode(int val) {if (head == nullptr) {return;}if (head->val == val) {ListNode* temp = head;head = head->next;delete temp;return;}ListNode* curr = head;while (curr->next != nullptr) {if (curr->next->val == val) {ListNode* temp = curr->next;curr->next = curr->next->next;delete temp;return;}curr = curr->next;}}// 打印链表void printList() {ListNode* curr = head;while (curr != nullptr) {std::cout << curr->val << " ";curr = curr->next;}std::cout << std::endl;}};2. 单链表插入节点在单链表中插入节点通常有两种情况:插入到链表的头部和插入到链表的尾部。

C语言链表结构(2)——单链表的增删改查

C语言链表结构(2)——单链表的增删改查

C语⾔链表结构(2)——单链表的增删改查单向链表的增删改查:1. 设计链表节点由于链表节点需要数据域以及指针域(存放着不同类型的数据),所以将每⼀个节点设计成⼀个结构体。

结构体模型:struct data{ /* 数据域 */ ... /* 指针域 */ ...};例⼦1:每⼀个节点都存放着⼀个整型数据,那么结构体如何定义?struct list_node{ int a; //数据域 struct list_node *next; //指针域};2. 初始化链表 -> 搞⼀个链表头struct list_node *init_list_head(struct list_node *head) //head = NULL{ //为头节点申请空间 head = (struct list_node *)malloc(sizeof(struct list_node)); if(head == NULL) printf("head malloc error!\n"); //为头节点的指针域赋值 head->next = NULL; return head;}3. 尾插数据 -> 在链表末尾增加⼀个新的节点int tail_add_list(struct list_node *head,int num){ //为新节点申请空间 struct list_node *Node = NULL; Node = (struct list_node *)malloc(sizoef(struct list_node)); //为新节点赋值 Node->a = num; Node->next = NULL; //寻找最后⼀个节点,并尾插 struct list_node *p = NULL; for(p=head;p->next!=NULL;p=p->next); //从循环出来时,p->next=NULL,也就是说,p指向最后⼀个节点! p->next = Node; return 0;}4. 遍历链表int show_list_node(struct list_node *head){ struct list_node *p = NULL; for(p=head->next;p!=NULL;p=p->next) { printf("%d\n",p->a); } return 0;}5. 头插 -> 在头节点之后插⼊⼀个新的节点。

循环单链表的增删改查

循环单链表的增删改查

循环单链表的增删改查
循环单链表是一种特殊的单链表,它的最后一个节点指向头节点,形成一个环形结构。

在循环单链表中,节点的插入、删除、修改和查找操作与普通单链表相似,但需要注意特殊的环形结构。

循环单链表的插入操作可以分为两种情况,一种是在头节点之前插入,另一种是在其他位置插入。

在头节点之前插入时,需要先将新节点的next指向原头节点,然后将最后一个节点的next指向新节点,最后将头节点指向新节点。

在其他位置插入时,需要先找到待插入节点的前一个节点,然后执行类似于普通单链表插入的操作。

循环单链表的删除操作也可以分为两种情况,一种是删除头节点,另一种是删除其他节点。

删除头节点时,需要先找到最后一个节点,然后将最后一个节点的next指向头节点的next,最后将头节点指向头节点的next。

删除其他节点时,需要先找到待删除节点的前一个
节点,然后执行类似于普通单链表删除的操作。

循环单链表的修改操作与普通单链表相似,需要先找到待修改节点,然后修改其数据域的值即可。

循环单链表的查找操作也与普通单链表相似,需要从头节点开始遍历链表,直到找到目标节点或遍历完整个链表。

总之,循环单链表在实现上与普通单链表相似,但需要特别注意其环形结构,在插入、删除和遍历时需要特殊处理。

- 1 -。

C语言链表实现增删改查

C语言链表实现增删改查
p1->next; free(p1);
} else {
for (int i=1;i<n-1;i++) {
p2=p2->next; } p2->next=p1->next; } return 0; } p1=p1->next; n++; } printf("Input Error!\n"); return 0; } int main() { struct stu *head=0,*s=0; //创建空 head=creat(s); //插入 insert(head); show(head); //修改 modify(head); show(head); //删除 del(head); show(head); return 0; }
printf("%ld\t%.2f\n",p1->id,p1->score); p1=p1->next; } printf("---------------\n"); } void insert(struct stu *head) { stu *p1; int n; printf("Enter the students number:\n"); scanf("%d",&n); for (int i=0;i<n;i++) {
#include <stdio.h> #include <stdlib.h> #define NULL 0 struct stu {
long id; float score; struct stu *next; }; void judge(long num) {

实现链表的插入和删除操作(C++)

实现链表的插入和删除操作(C++)

实现链表的插入和删除操作(C++)链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

链表的特点是插入和删除操作的时间复杂度为O(1),即常数时间复杂度。

这使得链表在需要频繁进行插入和删除操作的场景下非常高效。

在C++中,可以通过定义一个节点类来实现链表的插入和删除操作。

节点类包含一个数据成员和一个指向下一个节点的指针成员。

具体实现如下:```cppclass Node {public:int data;Node* next;};class LinkedList {private:Node* head;public://构造函数,初始化链表为空LinkedList() {head = nullptr;}//插入操作,在链表头部插入一个节点void insert(int value) {Node* newNode = new Node; newNode->data = value;newNode->next = head;head = newNode;}//删除操作,删除链表中第一个匹配给定值的节点void remove(int value) {Node* curr = head;Node* prev = nullptr;while (curr != nullptr && curr->data != value) { prev = curr;curr = curr->next;}if (curr == nullptr) {//未找到匹配的节点return;}if (prev == nullptr) {//要删除的节点为头节点head = curr->next;}else {//要删除的节点不为头节点prev->next = curr->next;}delete curr;}};```上述代码定义了一个链表类LinkedList,其中包含了插入和删除操作的实现。

单链表以及单链表的建立、清空、插入、删除、查找、修改等运算

单链表以及单链表的建立、清空、插入、删除、查找、修改等运算
{ int i,num,n;
int size=sizeof(struct lian_node); struct lian_node *llist,*tail,*p; llist=tail=NULL; printf("请输入链表长度 n="); scanf("%d",&n); printf("请输入链表的各个值:"); for(i=1;i<=n;i++){
return llist;
}
/*查找值*/ void SearchDoc_num(struct lian_node*llist,int num) { struct lian_node *ptr; if(llist==NULL){
printf("\n 无结果!\n"); return; } for(ptr=llist;ptr;ptr=ptr->link){ if(ptr->num==num){ printf("输出序号为 : %d\n\n",ptr->n); break; }
#include<stdio.h> #include<stdlib.h> #include<string.h>
struct lian_node{ int n; int num; struct lian_node*link; };
/*单个链表节点的结构体*/
struct lian_node*Create_Lian_Doc(); 一个只有 6 个结点的单链表,并输出该链表*/ void SearchDoc_n(struct lian_node*link,int n); 序号为 n 的结点,并输出*/ void SearchDoc_num(struct lian_node*link,int num); 为 x 的结点,并输出*/ void InsertDoc(struct lian_node*llist,struct lian_node*p,int n); 和值 x。在序号为 n 的结点后插入 x,并输出该链表*/ void DeleteDoc(struct lian_node*llist,int n); 号 n,删除序号为 n 的结点,并输出该链表*/ void Print_Lian_Doc(struct lian_node*llist);

单链表的插入与删除

单链表的插入与删除

单链表的插入与删除参考:/3jk/c/2010/0820/11016.html 最近不是太忙,整理些东西,工作也许用得到。

在链表这种特殊的数据结构中,链表的长短需要根据具体情况来设定,当需要保存数据时向系统申请存储空间,并将数据接入链表中。

对链表而言,表中的数据可以依此接到表尾或连结到表头,也可以视情况插入表中;对不再需要的数据,将其从表中删除并释放其所占空间,但不能破坏链表的结构。

这就是下面将介绍的链表的插入与删除。

1. 链表的删除如创建一个学生学号及姓名的单链表,即节点包括学生学号、姓名及指向下一个节点的指针,链表按学生的学号排列。

再从键盘输入某一学生姓名,将其从链表中删除。

首先定义链表的结构:从链表中删除一个节点有三种情况,即删除链表头节点、删除链表的中间节点、删除链表的尾节点。

题目给出的是学生姓名,则应在链表中从头到尾依此查找各节点,并与各节点的学生姓名比较,若相同,则查找成功,否则,找不到节点。

由于删除的节点可能在链表的头,会对链表的头指针造成丢失,所以定义删除节点的函数的返回值定义为返回结构体类型的指针。

[cpp] view plaincopystruct node *delet(head,pstr)/*以head 为头指针,删除pstr所在节点*/ struct node *head; char *pstr; { struct node*temp,*p; temp = head; /* 链表的头指针*/ if (head==NULL)/*链表为空*/ printf("\nListis null!\n"); else /*非空表*/{ temp = head; while (strcmp(temp-&gt;str,pstr)!=0&amp;&amp;temp-&gt;next!= NULL)/* 若节点的字符串与输入字符串不同,并且未到链表尾*/ { p = temp;temp = tmep-&gt;next;/* 跟踪链表的增长,即指针后移*/ } if(strcmp(temp-&gt;str,pstr)==0) /*找到字符串*/ { if(temp==head) { /* 表头节点*/ printf("deletestring :%s\n",temp-&gt;str); head =head-&gt;next; free(temp);/*释放被删节点*/ } else{ p-&gt;next=temp-&gt;next; /*表中节点*/ printf("delete string :%s\n",temp-&gt;str);free(temp); } } elseprintf("\nno find string!\n");/*没找到要删除的字符串*/ } return(head); } 2. 链表的插入首先定义链表的结构:[cpp] view plaincopystruct { int num; /*学生学号* /char str[20]; /*姓名* / struct node *next; } ;在建立的单链表中,插入节点有三种情况,如图所示;插入的节点可以在表头、表中或表尾。

python实现链表的增删改查(双向链表)

python实现链表的增删改查(双向链表)

python实现链表的增删改查(双向链表) ###节点类###三个属性,节点值,前向指针,后向指针class Node():def__init__(self,value,next,prev):self.value = valueself.next = nextself.prev = prev###操作链表类class Link():def__init__(self,value):self.link_create(value) #链表元素个数def link_count(self):print("link's len is %d"%self.count) #创建链表def link_create(self,value):self.head = Node(value,None,None)self.tail = self.headself.count = 1#在链表指定位置添加元素def link_push_index(self,index,value):temp_next = Node(value,None,None)if index <= 1: #index < 1时,头加temp_next.next = self.headself.head = temp_nextelif index >= self.count: #index >链表长度时,尾加self.tail.next = temp_nexttemp_next.prev = self.tailself.tail = temp_nextelse: #链表指定位置加num = 1temp_node = self.headwhile num != index:num = num + 1temp_node = temp_node.nexttemp_node_prev = temp_node.prevtemp_node.prev = temp_nexttemp_next.next = temp_nodetemp_next.prev = temp_node_prevtemp_node_prev.next = temp_nextself.count += 1 #添加元素-默认尾加def link_push(self,value):temp_next = Node(value,None,None)temp_prev = self.tailself.tail.next = temp_nextself.tail = temp_nextself.tail.prev = temp_prevself.count += 1#删除指定位置元素def link_pop_index(self,index):if index <= self.count and index > 0:if index == 1:temp_node = self.headself.head = temp_node.nextelse:temp_num = 1temp_node = self.headwhile temp_num != index :temp_node = temp_node.nexttemp_num = temp_num + 1temp_node.prev.next = temp_node.nexttemp_node.next.prev = temp_node.prevself.count -= 1else:print("Error:the link only have %d node"%self.count) #删除第⼀个找到的⽬标元素def link_pop_value_one(self,value):if self.count >0:if value == self.head.value:temp_node = self.headself.head = temp_node.nextself.count -= 1else:temp_node = self.headwhile temp_node != None and temp_node.value != value: temp_node = temp_node.nextif temp_node == None:print("the link not have %s"%value)else:temp_node.prev.next = temp_node.nexttemp_node.next.prev = temp_node.prevself.count -= 1else:print("the link is empty!") #删除链表中全部⽬标元素def link_pop_value_all(self,value):if self.count >0:temp_node = self.headwhile temp_node != None:if self.head.value == value:temp_node = self.headself.head = temp_node.nexttemp_node = self.headself.count -= 1else:if temp_node.value == value: if temp_node.next != None:temp_node.prev.next = temp_node.nexttemp_node.next.prev = temp_node.prevelse:self.tail = temp_node.prevself.tail.next = Noneself.count -= 1temp_node = temp_node.nextelse:print("the link is empty!") #修改指定位置元素的值def link_alter_index(self,num,value):temp_node = self.headtemp_num = 1if num > 0 and num <= self.count:while temp_num != num:temp_num += 1temp_node = temp_node.nexttemp_node.value = valueelse:print("Error:the link only have %d node"%self.count) #修改第⼀个找到的⽬标元素的值def link_alter_value_one(self,value_old,value_new):temp_node = self.headwhile temp_node != None and temp_node.value != value_old: temp_node = temp_node.nextif temp_node == None:print("the link not have %s"%value_old)else:temp_node.value = value_new #修改链表中全部⽬标元素的值def link_alter_value_all(self,value_old,value_new):temp_node = self.headwhile temp_node != None:if temp_node.value == value_old:temp_node.value = value_newtemp_node = temp_node.next #打印链表(正序)def link_print(self):temp_node = self.headwhile temp_node != None:print temp_node.valuetemp_node = temp_node.next#调⽤及结果#创建链表head = Link("head") for i in range(8):head.link_push(i) head.link_print()head.link_count()head.link_pop_index(2) #删除第2个元素head.link_print()head.link_count()head.link_push(5) #添加元素5head.link_print()head.link_count()head.link_push_index(3,1000) #在第三个位置添加 1000head.link_print()head.link_count()head.link_pop_value_one(1000) #删除元素1000 head.link_print()head.link_count()head.link_pop_value_all(5) #删除所有元素5 head.link_print()head.link_count()head.link_alter_index(1,1995)head.link_print()head.link_count()head.link_alter_value_one(15,5)head.link_print()head.link_count()head.link_alter_value_all(5,118)head.link_print()head.link_count()。

单链表增删查改

单链表增删查改

单链表增删查改构建⼀个单链表,链表中存储的是⽤户输⼊的整数⼀、实现了以下功能:1. 链表初始化2. 链表判空3. 在指定结点之后添加结点4. 在指定结点之前添加结点(思路重要)5. 删除指定结点p6. 结点添加------⾸添&尾添7. 遍历并输出链表8. 查找链表的元素------按位序查找(封装起来,在List_Insert和List_DeleteByOrder这两个函数中调⽤)&按值查找9. 删除链表的元素------按值删除&按位删除10. 更改链表的指定元素11. 在链表的指定位置添加元素12. 在链表的指定位置添加元素(引⼊链表长度pList->size)13. 链表的清空⼆、亮点:⽤⾃⼰定义的数据结构struct _list表⽰整个链表 该结构中存放了⼀个始终指向头结点的指针head,⼀个始终指向尾结点的指针tail,⼀个表⽰单链表长度的变量size 指针head和tail给链表的结点添加带来⽅便,不需要遍历整个链表(函数List_AddOnTail) 变量size给在链表指定位置添加结点带来⽅便,可以简化代码(函数List_Insert)三、存在的问题(放在另⼀个随笔中):在函数List_DeleteByValue中:链表中存在多个相同的元素相邻时,⽆法全部删除(重点是相邻,相同元素不相邻时均可删除)只能删除第偶数个位置的元素解决⽅法:1. 空间:将原来的链表进⾏拷贝(或者做⼀个辅助数组),对原来的链表进⾏判断,对备份链表进⾏删除操作(数据量太⼤时不推荐)2. 时间:不改动删除算法,⽤这个算法对这个链表进⾏多次操作,直到删除完为⽌3. 再加⼀个指针:prev,使⽤三指针⽅法解决代码执⾏结果如下:代码如下:1 # include <stdio.h>2 # include <stdlib.h>3 # include <stdbool.h>4//定义结构体(结点)5 typedef struct _node {6int value;7struct _node * next;8 } Node;910//定义数据结构struct _list表⽰整个链表11//存放链表的信息:头结点(如果有的话)或⾸结点、尾结点、链表长度等等12 typedef struct _list13 {14 Node* head;//始终指向⾸结点15 Node* tail;//始终指向尾结点16int size;//表⽰链表的长度,⽤在List_Insert函数中,⽤来判断输⼊的位置i是否越界,可以简化代码 17 } List;18//初始化链表19bool InitList(List* pList)20 {21 pList->head = pList->tail = NULL;22 pList->size = 0;23return true;24 }25//判空26bool Empty(List* pList)27 {28return (pList->head==NULL);29 }3031//在指定结点之后添加结点32bool InsertNextNode(Node* p, int elem)33 {34bool sign = true;35if(p == NULL)36 {37 sign = false;38 }39 Node* s = (Node*)malloc(sizeof(Node));40if(s == NULL)//内存分配失败41 {42 sign = true;43 }44 s->value = elem;45 s->next = p->next;46 p->next = s;4748return sign;49 }50//在指定节点之前添加结点51/*52偷天换⽇的操作!53指定结点的前驱结点是未知的,从头结点遍历的话时间复杂度⾼O(n)54虽然结点不能交换位置,但是结点中的数据可以交换位置[O(1)]55*/56bool InsertPriorNode(Node* p, int elem)57 {58bool sign = true;59if(p == NULL)60 {61 sign = false;62 }63 Node* s = (Node*)malloc(sizeof(Node));64if(s == NULL)65 {66 sign = false;67 }68//连接69 s->next = p->next;70 p->next = s;71//下⾯两个语句是精髓72 s->value = p->value;//将结点p中的元素复制到s中73 p->value = elem;//p中元素替换为elem7475return sign;76 }77//删除指定结点p(局限:当该结点是尾结点时,⽆法完成操作)78bool DeleteNode(Node* p)79 {80bool sign = true;81if(p == NULL)82 {83 sign = false;84 }85 Node* q = p->next;//q指向p的后继结点86 p->value = p->next->value;//p结点和它的后继结点交换数据87 p->next = q->next;//将q结点删除88free(q);8990return sign;91 }92//结点添加(尾添加)93 Node* List_AddOnTail(List* pList, int number)//传⼊指针的指针94 {95//分配结点空间,并写⼊p->value96 Node* p = (Node*)malloc(sizeof(Node));97 p->value = number;98 p->next = NULL;99//head始终指向⾸结点,tail始终指向尾结点100//如果链表是空的,最新分配的结点(p)既是head,也是tail101if(pList->head == NULL)102 {103 pList->head = p;104 pList->tail = p;105 }106//如果链表不是空的,只需要处理tail107else108 {109 pList->tail->next = p;//此时链表的尾结点要指向新分配的结点110 pList->tail = p;//新分配的结点成为链表的tail111 }112 pList->size ++;113 pList->tail->next = NULL;//tail⾥⾯的指针必须是NULL 114115/* //在链表的尾结点之后添加结点,需要循环,116 Node* last = pList->head;117 if(last)118 {119 while(last->next)120 {121 last = last->next;122 }123 //接上去124 last->next = p;125 }126 else127 {128 pList->head = p;129 }130*/131return pList->head;132 }133//结点添加(头添)134 Node* List_AddOnHead(List* pList, int n)135 {136 Node* p = (Node*)malloc(sizeof(Node));137 p->value = n;138 p->next = NULL;139if(pList->head == NULL)140 {141 pList->head = p;142 pList->tail = p;143 }144else145 {146 p->next = pList->head;147 pList->head = p;148 }149 pList->size ++;150return pList->head;151 }152//遍历输出链表153void List_Print(List* pList)154 {155 Node* p;156for(p=pList->head; p; p=p->next)157 {158 printf("%-5d", p->value);159 }160 printf("\n");161 }162//查(按位)163 Node* List_GetElem(List* pList, int i)164 {165 Node* q;166if(i<1 || i>pList->size)167 q = NULL;168else169 {170 Node* p = pList->head;171int j = 1;172while(j<i)173 {174 p = p->next;175 j++;176 }177 q = p;178 }179180return q;181 }182//查(按值)183bool List_Search(List* pList, int number)184 {185bool isFound = false;186 Node* p;187for(p=pList->head; p; p=p->next)188 {189if(p->value == number)190 {191 isFound = true;192break;193 }194 }195return isFound;196 }197//按值删除元素(仅删除第⼀个)198void List_DeleteByValue(List* pList, int number)199 {200 Node* prev;201 Node* p;202 Node* q;203for(p=pList->head,q=NULL; p; q=p,p=p->next)204 {205if(number == p->value)206 {207if(q)208 {209 q->next = p->next;210 }211else212 {213 pList->head = p->next;214 }215free(p);216break;217 }218 }219 }220//更改指定元素221void List_Change(List* pList, int a, int b)222 {223 Node* p;224for(p=pList->head; p; p=p->next)225 {226if(p->value == a)227 {228 p->value = b;229 }230 }231 }232//在指定位置添加元素,引⼊链表长度(pList->size)233bool List_Insert(List* pList, int i, int elem)234 {235bool sign = true;236if(i<1 || i>pList->size+1)237 sign = false;238else if(i == 1)239 {240 Node* s = (Node*)malloc(sizeof(Node));241 s->value = elem;242 s->next = pList->head;243 pList->head = s;244 }245//找到第i-1个结点246else247 {248 Node* p = List_GetElem(pList, i-1);//封装找到第i-1个结点,注意这⾥传⼊的参数是List*类型249 sign = InsertNextNode(p,elem);//封装在第i-1个结点之后插⼊新结点250 }251return sign;252 }253//按位序删除元素254bool List_DeleteByOrder(List* pList, int i, int* elem)255 {256bool sign = true;257if(i<1 || i>pList->size+1)258 sign = false;259else if(i == 1)260 {261 Node* p = pList->head;262 pList->head = p->next;263free(p);264 }265//找到第i-1个结点266else267 {268 Node* p = List_GetElem(pList, i-1);//简单的封装注意这⾥传⼊的参数是List*类型269if(p==NULL || p->next==NULL)//i值越界或者第i-1个结点没有后继结点270 {271 sign = false;272 }273 Node* q = p->next;274 *elem = q->value;275 p->next = q->next;276free(q);277 }278return sign;279 }280//清除链表281bool List_Clear(List* pList)282 {283 Node* p;284 Node* q;285bool sign = true;286if(pList->head == NULL)287 sign = false;288 p = pList->head->next;289while(p)290 {291 q = p->next;292free(p);293 p = q;294 }295 pList->head->next = NULL;//注意不能少296return sign;297 }298299int main(void)300 {301//创建并初始化,输⼊元素302 List list;303 InitList(&list);304int number;305 printf("请输⼊整数(输⼊-1结束):\n");306do307 {308 scanf("%d", &number);309if(number != -1)310 {311 list.head = List_AddOnTail(&list, number);//注意这⾥要传⼊head的地址312//list.head = List_AddOnHead(&list, number);313 }314 }while(number != -1);315//遍历并输出链表316 printf("链表中的元素为:");317 List_Print(&list);318//查(按值)319 printf("\n请输⼊您要查找的元素:");320 scanf("%d", &number);321if(List_Search(&list, number) == true)322 {323 printf("找到了!\n");324 }325else326 {327 printf("没找到!\n");328 }329//查(按位)330 printf("请输⼊您要查找的位序:");331int i, elem;332 scanf("%d", &i);333if(List_GetElem(&list, i) != NULL)334 {335 printf("找到了!该元素是%d\n", List_GetElem(&list, i)->value);//这个地⽅的写法有问题吗?336 }337else338 {339 printf("位序越界!\n");340 }341//删除,按元素值342 printf("\n请输⼊您要删除的元素:");343 scanf("%d", &number);344if(List_Search(&list, number) == true)345 {346 List_DeleteByValue(&list, number);347 printf("删除成功!当前链表中的元素为:");348 List_Print(&list);349 }350else351 {352 printf("删除失败!您要删除的元素不存在!\n");353 }354355//更改链表元素356int a, b;357 printf("\n请输⼊旧元素:");358 scanf("%d", &a);359if(List_Search(&list, a))360 {361 printf("请输⼊新元素:");362 scanf("%d", &b);363 List_Change(&list, a, b);364 printf("更改成功!当前链表元素为:");365 List_Print(&list);366 }367else368 {369 printf("未找到!\n");370 }371//插⼊元素372 printf("\n请输⼊您要插⼊的位置和数字:");373 scanf("%d%d", &i, &elem);374if(List_Insert(&list, i, elem))375 {376 printf("插⼊成功!当前链表元素为:");377 List_Print(&list);378 }379else380 {381 printf("插⼊失败!\n");382 }383//按位序删除元素384 printf("\n请输⼊您要删除的结点的位序:");385 scanf("%d", &i);386if(List_DeleteByOrder(&list, i, &elem))387 {388 printf("删除成功!删除的元素为:%d\n当前链表元素为:", elem);389 List_Print(&list);390 }391else392 {393 printf("删除失败!\n");394 }395396//链表清除397if(List_Clear(&list))398 {399 printf("\n链表已清空!\n");400 }401else402 {403 printf("\n清空失败,链表为空\n");404 }405406return0;407 }。

删除单链表中的最大值的算法

删除单链表中的最大值的算法

删除单链表中的最大值的算法1. 引言单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

在实际应用中,我们经常需要对单链表进行各种操作,如插入、删除、查找等。

本文将重点介绍一种删除单链表中最大值的算法。

2. 算法思路要删除单链表中的最大值,首先需要找到最大值所在的节点,并记录其前驱节点。

然后,将前驱节点的指针指向最大值节点的下一个节点,从而完成删除操作。

具体步骤如下: 1. 初始化最大值为链表头结点的数据元素,并将其前驱节点设为头结点。

2. 遍历整个链表,比较每个节点的数据元素与当前最大值。

3. 如果找到更大的数据元素,则更新最大值和前驱节点。

4. 遍历结束后,如果最大值所在的节点不是头结点,则将其前驱节点的指针指向最大值节点的下一个节点。

3. 算法实现以下是使用Python语言实现删除单链表中最大值的算法:class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextdef delete_max_value(head):if not head or not head.next:return headmax_val = head.valmax_prev = headcur = head.nextwhile cur:if cur.val > max_val:max_val = cur.valmax_prev = prevprev = curcur = cur.nextif max_prev == head:return head.nextmax_prev.next = max_prev.next.nextreturn head4. 算法分析时间复杂度分析:•遍历单链表需要O(n)的时间复杂度,其中n是链表的长度。

•在遍历过程中,比较每个节点的数据元素需要O(1)的时间复杂度。

删除单链表中的最大值的算法

删除单链表中的最大值的算法

删除单链表中的最大值的算法一、引言单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

在实际应用中,我们常常需要对单链表进行各种操作,例如插入、删除、查找等。

本文将探讨如何删除单链表中的最大值。

二、问题分析删除单链表中的最大值是一个常见的问题,解决这个问题的关键是找到最大值所在的节点,并删除该节点。

具体而言,我们需要遍历整个单链表,记录当前最大值所在的节点以及该节点的前驱节点,然后将前驱节点与当前节点的后继节点相连,从而实现删除操作。

三、算法设计为了删除单链表中的最大值,我们可以采用以下算法设计:1. 初始化变量•定义一个指向单链表头节点的指针head,并初始化为单链表的第一个节点。

•定义一个指向当前最大值节点的指针max_node,并初始化为head。

•定义一个指向当前最大值节点的前驱节点的指针previous_node,并初始化为null。

2. 遍历单链表我们通过遍历单链表的方式找到最大值节点,并记录最大值节点的前驱节点。

while (head != null) {if (head.value > max_node.value) {max_node = head;}head = head.next;}3. 删除最大值节点根据前面的遍历过程,我们已经找到了最大值节点max_node以及其前驱节点previous_node,现在我们需要执行删除操作。

if (max_node == head) {// 如果最大值节点是头节点head = head.next;} else {// 如果最大值节点不是头节点previous_node.next = max_node.next;}最后,我们成功地删除了单链表中的最大值节点。

四、算法分析1. 时间复杂度遍历单链表的时间复杂度为O(n),其中n为单链表的节点数。

因为我们需要找到最大值节点,所以需要遍历整个单链表。

删除节点的时间复杂度为O(1),直接修改指针即可。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
print(head);
return 0;
}
下面是程序执行结果:
Please input the data: 1
Please input the data: 2
Please input the data: 3
Please input the data: 4
Please input the data: 0
return p;
}
//单链表节点插入
//在单链表pos位置处插入节点,返回链表头指针
//pos从0开始计算,0表示插入到head节点后面
node *insert_node(node *head, int pos, int data)
{
node *item = (node *)malloc(sizeof(node));
{
printf("incorrect position to search node!\n");
return NULL;
}
if(0 == pos)
{
return head;
}
if(NULL == p)
{
printf("Link is empty!\n"); //链表为空
单链表的结构是数据结构中最简单的,它的每一个节点只有一个指向后一个节点的指针。
单链表的创建:
typedef struct node
{
int data; //节点内容
node *next; //下一个节点
}node;
//创建单链表
node *create()
{
int i=0; //链表中数据的个数
The 1th node is: 1
The 2th node is: 5
The 3th node is: 3
The 4th node is: 4
Press any key to continue
node *head, *p, *q;
int x = 0;
head = (node *)malloc(sizeof(node)); //创建头节点
while(1)
{
printf("Please input the data: ");
scanf("%d", &x);
node *p = NULL;
item->data = data;
if(0 == pos) //插入链表头后面
{
head->next = item; //head后面是item
return head;
}
p = search_node(head, pos); //获得位置pos的节点指针
//单链表的测长
int length(node *head)
{
int len = 0;
node *p = head->next;
while(NULL != p)
{
len++;
p = p->next;
}
return len;
}
//打印链表
void print(node *head)
return NULL;
}
p = search_node(head, pos-1); //获得位置pos的节点指针
if(NULL != p && NULL != p->next)
{
del = p->next;
p->next = del->next;
delete del;
if(NULL != p)
{
item->next = p->next; //item指向原pos节点的后一个节点
p->next = item; //把item插入到pos的后面
}
return head;
}
//单链表节点删除
//删除单链表的pos位置的节点,返回链表头指针
}
else
{
q->next = p; //连接到链表尾端
}
q = p; //q指向末节点
}
q->next = NULL; //链表的最后一个指针为NULL
return head;
}
上面的代码中,while循环每次从终端读入一个整型数据,并调用malloc动态分配链表节点内存存储这个整型数据,然后在插入到单链表的末尾;最后当数据为0时表示插入数据结束,此时把末尾节点的next指针置为NULL。
printf("insert integer 5 after 2th node: \n");
print(head); //打印单链表
head = delete_n;delete the 2th node: \n");
//pos从1开始计算,1表示删除head后的第一个节点
node *delete_node(node *head, int pos)
{
node *del;
node *p = head->next;
if(NULL == p) //链表为空
{
printf("Link is empty!\n");
{
int pos = 0;
node *p = NULL;
if(NULL == head->next)
{
printf("Link is empty!\n");
return ;
}
p = head->next;
while(NULL != p) //遍历链表
{
printf("The %dth node is: %d\n", ++pos, p->data);
}
return head;
}
下面代码是上面各个函数的测试主程序:
int main()
{
node *head = create(); //创建单链表
printf("Length: %d\n", length(head)); //测量单链表长度
head = insert_node(head, 2, 5); //在第2个节点之后插入5
return NULL;
}
while(--pos)
{
if((p = p->next) == NULL)
{
printf("incorrect position to search node!\n");
break; //超出链表返回
}
}
p = p->next;
}
}
//单链表的节点查找
//查找pos位置的节点,返回节点指针
//pos从0开始,0返回head节点
node *search_node(node *head, int pos)
{
node *p = head->next;
if(pos < 0) //pos位置不正确
Length: 4
insert integer 5 after 2th node:
The 1th node is: 1
The 2th node is: 2
The 3th node is: 5
The 4th node is: 3
The 5th node is: 4
delete the 2th node:
if(0 == x) //data为0时创建结束
{
break;
}
p = (node *)malloc(sizeof(node));
p->data = x;
if(++i == 1) //链表只有一个元素
{
head->next = p; //连接到head的后面
相关文档
最新文档