带头结点单链表基本操作参考代码

合集下载

单链表头插法代码

单链表头插法代码

单链表头插法代码单链表是一种常见的数据结构,它由多个节点组成,每个节点包括两部分:一个数据存储区和一个指向下一个节点的指针。

插入操作是单链表的基本操作之一,在插入一个节点时,可以采用两种方法:头插法和尾插法。

在本篇文章中,我们将重点讲解单链表的头插法。

头插法是指在单链表的头节点之前插入一个新节点。

这种方法需要先创建一个新节点,并将其指针指向原头节点所指向的节点。

然后再将头节点的指针指向新节点。

相当于是在链表的头部插入新节点。

下面是头插法的代码实现:```struct node {int data;struct node *next;};void insert_node(struct node **head, int value) {struct node *new_node = (struct node*)malloc(sizeof(struct node));new_node->data = value;new_node->next = *head;*head = new_node;}```在上面的代码中,我们首先定义了一个节点结构体node,其中包含一个int类型的数据成员data和一个指向下一个节点的指针成员next。

然后,我们定义一个函数insert_node,这个函数的作用是向单链表中插入新的节点。

其中,head是指向链表头节点的指针,value 是要插入的节点的值。

在insert_node函数体中,我们首先通过malloc函数动态分配内存,创建一个新节点new_node。

然后,将新节点的data成员赋值为value,将新节点的next指针指向原head指针所指向的节点,最后将head指针指向新节点new_node。

这样,新节点就插入到链表的头部了。

总结一下,头插法是单链表中比较常用的一种插入节点的方式,通过这种方法,可以很方便地在链表头部插入新节点。

在实现的过程中需要注意,在创建新节点时要手动分配内存,否则会发生内存错误。

数据结构-单链表基本操作实现(含全部代码)

数据结构-单链表基本操作实现(含全部代码)

数据结构-单链表基本操作实现(含全部代码)今天是单链表的实现,主要实现函数如下:InitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。

最坏是O(n),即从头查找p之前的结点,然后删除p所指结点LocateElem(LinkList L,ElemType e) 参数:单链表L,元素e 功能:查找第⼀个等于e的元素,返回指针时间复杂度O(n)代码:/*Project: single linkeed list (数据结构单链表)Date: 2018/09/14Author: Frank YuInitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。

15.带头结点的单链表L,设计一个算法使元素递增有序

15.带头结点的单链表L,设计一个算法使元素递增有序

15.带头结点的单链表L,设计⼀个算法使元素递增有序#include<stdio.h>#include<stdlib.h>typedef int ElemType;typedef struct LNode{ElemType data;struct LNode *next;}LNode,*LinkList;//尾插法LinkList List_TailInsert(LinkList &L){int x;L=(LinkList)malloc(sizeof(LNode));LNode *s,*r=L;printf("请输⼊单链表各个节点,以9999结束!\n");scanf("%d",&x);while(x!=9999){s=(LNode*)malloc(sizeof(LNode));s->data=x;r->next=s;r=s;scanf("%d",&x);}r->next=NULL;return L;}//带头结点的单链表L,设计⼀个算法使元素递增有序void Sort(LinkList &L){LNode *pre,*p=L->next,*r=p->next;p->next=NULL;//将p与后⾯的链表断开,直接插⼊排序p=r;while(p!=NULL){r=p->next;//找到p的后续节点防⽌断链pre=L;//每次断开的链表中找到合适的p之前的位置while(pre->next!=NULL&&pre->next->data<p->data)pre=pre->next;//执⾏结束就找得到了p之前的位置p->next=pre->next;//将p插⼊到前⾯的有序链表中pre->next=p;p=r;}}int main(){LinkList L;LinkList R;//接收处理结果R=List_TailInsert(L);Sort(R);LNode *p=R;while(p->next!=NULL){p=p->next;printf("->%d",p->data);}}。

JAVA数据结构——单链表的操作

JAVA数据结构——单链表的操作

单链表的操作方法一:package ch02;(1)建立结点类Node.javapublic class Node {public Object data;//存放结点数据值public Node next;//存放后继结点//无参构造函数public Node(){ this(null,null);}//只有结点值的构造函数public Node(Object data){ this(data,null);}//带有节点值和后继结点的构造函数public Node(Object data,Node next){ this.data=data;this.next=next;}}(2)建立链表及操作LinkList.javapackage ch02;import java.util.Scanner;public class LinkList implements IList{public Node head;//单链表的头指针//构造函数初始化头结点public LinkList(){head=new Node();}//构造函数构造长度为n的单链表public LinkList(int n,boolean Order) throws Exception{ this();if(Order)create1(n); //头插法顺序建立单链表elsecreate2(n); //尾插法逆序建立单链表}//头插法顺序建立单链表public void create1(int n) throws Exception{Scanner sc=new Scanner(System.in);System.out.println("请输入结点的数据(头插法):”);for(int i=0;i<n;i++){insert(0,sc.next());}}//尾插法逆序建立单链表public void create2(int n) throws Exception{Scanner sc=new Scanner(System.in);System. out.println("请输入结点的数据(尾插法):");for(int i=0;i<n;i++){insert(length(),sc.next());}}//将链表置空public void clear(){head.data=null;head.next=null;}//判断链表是否为空public boolean isEmpty(){return head.next==null;}//返回链表长度public int length(){Node p=head.next;int length=0;while(p!=null){p=p.next;length++;//返回P不空长度length加1}return length;}//读取并返回第i个位置的数据元素public Object get(int i) throws Exception {Node p=head.next;int j;//从首结点开始向后查找,直到9指向第i个结点或者p为nullfor(j=0;j<i&&p!=null;j++){ p=p.next;}if(j>i||p==null)//i不合法时抛出异常throw new Exception("第"+i+”个数据元素不存在”);return p.data;}//插入乂作为第i个元素public void insert(int i, Object x) throws Exception{ Node p=head;int j=-1;//寻找第i个结点的前驱i-1while(p!=null&&j<i-1){p=p.next;j++;}if(j>i-l||p==null)//i不合法时抛出异常throw new Exception("插入位置不合法”);Node s=new Node(x);s.next=p.next;p.next=s;}//删除第i个元素public void remove(int i) throws Exception{ Node p=head;int j=-1;while(p!=null&&j<i-1){//寻找第i-1 个节点p=p.next;j++;}if(j>i-1||p.next==null)throw new Exception("删除位置不合法”);p.next=p.next.next;}//返回元素x首次出现的位序号public int indexOf(Object x) {Node p=head.next;int j=0;while(p!=null&&!p.data.equals(x)){p=p.next;j++;if(p!=null)return j;elsereturn -1;}public void display(){Node p=head.next;while(p!=null){if(p.next==null)System.out.print(p.data);elseSystem.out.print(p.data+"f );p=p.next;}}}(3)建立测试类Test.javappublic class test {public static void main(String[] args) throws Exception { // TODO Auto-generated method stubScanner sc=new Scanner(System.in);boolean or;int xz,xx;System.out.println("请选择插入的方法:0、头插法,1、尾插法");xz=sc.nextInt();if(xz!=0)or=true;elseor=false;System. out.println("请插入的结点的个数:”);xx=sc.nextInt();LinkList L=new LinkList(xx,or);System.out.println("建立的链表为:");L.display();System.out.println();System.out.println("链表的长度:"+L.length());System. out.println(”请输入查找的结点的数据:”);Object x=sc.next();int position=L.indexOf(x);System.out.println("结点的数据为:"+x+"的位置为:"+position); System. out.println("请输入删除的结点的位置:”);int sr=sc.nextInt();L.remove(sr);L.display();System.out.println();System.out.println("链表的长度:"+L.length()); }品P rob I em & J a vs d oc / Declaration Q Error Log 里Con sole-M、、■=:termin8ted> test [3] [Java Application] C U &ert\Ad im i n i st rat o r\Ap p Data\L o cs I请选择插入.的方法:0、头插法,lv星插法请插入的特点的个数:请愉入结点的颓据(尾插法):A B C E D F建立的旌表为;A+B T C+E T D+F链表的长度:6请输入查找的结点的数据:结点的数据为:E的位置为:3请输入删除的结点的位置,R+B T E+DW道表的长度:S方法二(引入get和set方法)Package sy;import java.util.Scanner;//单链表的结点类public class Node {private Object data; //存放结点值private Node next; //后继结点的引用public Node() { //无参数时的构造函数this(null, null);}public Node(Object data) { // 构造值为data 的结点this(data, null);}public Node(Object data, Node next) {//构造值为data 和next 的结点构造函数this.data = data;this.next = next;}public Object getData() { return data;}public void setData(Object data) {this.data = data;}public Node getNext() { return next;public void setNext(Node next) { this.next = next;}}//实现链表的基本操作类public class LinkList {Node head=new Node();//生成一个带头结点的空链表//根据输入的一系列整数,以0标志结束,用头插法建立单链表public void creat() throws Exception {Scanner sc = new Scanner(System.in); //构造用于输入的对象for (int x=sc.nextInt(); x!=0; x=sc.nextInt()) //输入若干个数据元素的值(以0结束) insert(0, x);//生成新结点,插入到表头}//返回带头结点的单链表中第i个结点的数据域的值。

实验二 链表操作实现

实验二 链表操作实现

实验二链表操作实现实验日期:2017 年 3 月16 日实验目的及要求1. 熟练掌握线性表的基本操作在链式存储上的实现;2. 以线性表的各种操作(建立、插入、删除、遍历等)的实现为重点;3. 掌握线性表的链式存储结构的定义和基本操作的实现;4. 通过本实验加深对C语言的使用(特别是函数的参数调用、指针类型的应用)。

实验内容已知程序文件linklist.cpp已给出学生身高信息链表的类型定义和基本运算函数定义。

(1)链表类型定义typedef struct {int xh; /*学号*/float sg; /*身高*/int sex; /*性别,0为男生,1为女生*/} datatype;typedef struct node{datatype data; /*数据域*/struct node *next; /*指针域*/} LinkNode, *LinkList;(2)带头结点的单链表的基本运算函数原型LinkList initList();/*置一个空表(带头结点)*/void createList_1(LinkList head);/*创建单链表*/void createList_2(LinkList head);/* 创建单链表*/void sort_xh(LinkList head);/*单链表排序*/void reverse(LinkList head);/*对单链表进行结点倒置*/void Error(char *s);/*自定义错误处理函数*/void pntList(LinkList head);/*打印单链表*/void save(LinkList head,char strname[]);/*保存单链表到文件*/任务一创建程序文件linklist.cpp,其代码如下所示,理解LinkList类型和基本运算函数后回答下列问题。

#include <stdio.h>#include <stdlib.h>/*单链表结点类型*/typedef struct {int xh; /*学号*/float sg; /*身高*/int sex; /*性别,0为男生,1为女生*/} datatype;typedef struct node{datatype data; /*数据域*/struct node *next; /*指针域*/} LinkNode, *LinkList;/*带表头的单链表的基本运算函数*/LinkList initList();/*置一个空表(带头结点)*/void createList_1(LinkList head);/*创建单链表*/void createList_2(LinkList head);/*创建单链表*/void sort_xh(LinkList head);/*单链表排序*/void reverse(LinkList head);/*单链表倒置*/void Error(char *s);/*自定义错误处理函数*/void pntList(LinkList head);/*打印单链表*/void save(LinkList head,char strname[]);/*保存单链表到文件*//*置一个空表*/LinkList initList(){ LinkList p;p=(LinkList)malloc(sizeof(LinkNode));p->next=NULL;return p;}/*创建单链表*/void createList_1(LinkList head){ FILE *fp;int xh;float sg;int sex;LinkList p;if((fp=fopen("records.txt","r"))==NULL){ Error("can not open file !");return ;}while(!feof(fp)){ fscanf(fp,"%d%f%d",&xh,&sg,&sex);p=(LinkList)malloc(sizeof(LinkNode));p->data.xh=xh;p->data.sg=sg;p->data.sex=sex;p->next=head->next;head->next=p;}fclose(fp);}/*创建单链表*/void createList_2(LinkList head){ FILE *fp;int xh;float sg;int sex;LinkList p,rear;if((fp=fopen("records.txt","r"))==NULL){ Error("can not open file !");return ;}rear=head;while(!feof(fp)){ fscanf(fp,"%d%f%d",&xh,&sg,&sex);p=(LinkList)malloc(sizeof(LinkNode));p->data.xh=xh;p->data.sg=sg;p->data.sex=sex;p->next=NULL;rear->next=p;rear=p;}fclose(fp);}/*单链表排序*/void sort_xh(LinkList head){LinkList q,p,u;p=head->next;head->next=NULL;/*利用原表头结点建新的空表*/while(p){ q=p; /*q为被插入的结点*/p=p->next;/*用p记录后继结点*//*遍历新链表查找插入位置*/u=head;while(u->next!=NULL)/*查找插入位置*/{ if(u->next->data.xh>q->data.xh)break;u=u->next;}/*插入在u结点的后面*/q->next=u->next;u->next=q;}}/*单链表倒置*/void reverse(LinkList head){ LinkList p, r;p=head->next;head->next=NULL;while(p){ r=p;p=p->next;/*r指向结点头插到链表*/r->next=head->next;head->next=r;}}/*输出单链表*/void pntList(LinkList head){ LinkList p;p=head->next;while(p!=NULL){printf("%2d: %.2f %d\n",p->data.xh,p->data.sg,p->data .sex);p=p->next;}}/*自定义错误处理函数*/void Error(char *s){ printf("\n %s", s);exit(1); /*返回OS,该函数定义在stdlib.h中*/}/*保存单链表到文件*/void save(LinkList head,char strname[]){ FILE *fp;LinkList p;if((fp=fopen(strname,"w"))==NULL){ printf("can not open file !");return ;}p=head->next;while(p!=NULL){ fprintf(fp,"%2d %5.2f %2d\n",p->data.xh,p->data.sg,p->data.sex);p=p->next;}fclose(fp);}请回答下列问题:(1)由单链表结点类型定义可知,该链表结点类型名为 LinkNode ,结点的指针类型为 LinkList ,向系统申请一个学生结点空间并把起始地址存于上述结点指针变量new 中的语句是: p=(LinkList)malloc(sizeof(LinkNode)); 。

带头结点的单链表求表长

带头结点的单链表求表长

在带头结点的单链表中,头结点是一个特殊的节点,它不存储具体的数据,而是用来表示链表的起始位置。

要求带头结点的单链表的表长(即节点的数量),可以遍历链表并计算节点的数量,不包括头结点。

下面是一个示例代码,展示了如何求带头结点的单链表的表长:
class Node:
def __init__(self, data=None):
self.data = data
self.next = None
def get_length(head):
count = 0
current = head.next # 从头结点的下一个节点开始
while current is not None:
count += 1
current = current.next
return count
# 创建带头结点的单链表示例
head = Node() # 创建头结点
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
head.next = node1
node1.next = node2
node2.next = node3
# 求表长
length = get_length(head)
print("表长为:", length)
在上述示例中,通过遍历链表中的节点并计数,我们可以得到带头结点的单链表的表长。

注意,链表的表长不包括头结点。

在这个示例中,链表的表长为3。

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法引言单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两部分:数据域和指针域。

其中,数据域用于存储数据,指针域用于指向下一个节点。

在单链表中,头结点是第一个节点之前的一个特殊节点,它不存储任何数据。

逆置(或反转)单链表是将原始链表中的节点顺序颠倒过来。

例如,给定一个单链表:1 -> 2 -> 3 -> 4 -> nullptr,逆置后的结果为:4 -> 3 -> 2 -> 1 -> nullptr。

本文将介绍如何实现带头结点单链表的逆置算法,并给出相应的C++代码实现。

算法思路要实现带头结点单链表的逆置算法,可以使用迭代或递归两种方法。

迭代方法迭代方法通过遍历原始链表中的每个节点,并修改其指针域来实现逆置。

具体步骤如下:1.如果链表为空或只有一个节点,则直接返回。

2.定义三个指针:prev、curr和next。

–prev指向当前节点的前一个节点(初始时为nullptr);–curr指向当前节点;–next指向当前节点的下一个节点。

3.进行循环,直到curr指向nullptr为止:–将curr的指针域修改为prev;–将prev指向curr;–将curr指向next;–将next指向下一个节点。

4.修改头结点的指针域为nullptr,将prev作为新的头结点。

递归方法递归方法通过逐层调用函数来实现逆置。

具体步骤如下:1.如果链表为空或只有一个节点,则直接返回。

2.定义一个递归函数reverseList,该函数接收一个参数:当前节点head。

3.递归终止条件:如果当前节点或当前节点的下一个节点为空,则返回当前节点。

4.在递归调用前,先逆置从下一个节点开始的子链表,并将返回结果保存在变量newHead中。

5.将当前节点的下一个节点的指针域修改为当前节点(即将子链表的尾部连接到当前节点)。

6.将当前节点的指针域修改为空(即将当前节点作为新链表的尾部)。

数据结构--实验报告 线性表的基本操作

数据结构--实验报告 线性表的基本操作

一、实验目的二、实验内容和要求三、源代码1)顺序表的代码2)单链表的代码四、测试结果1)顺序表的测试结果2)单链表的测试结果五、心得体会实验一线性表的基本操作及其应用一、实验目的1、帮助读者复习C++语言程序设计中的知识。

2、熟悉线性表的逻辑结构。

3、熟悉线性表的基本运算在两种存储结构上的实现。

4、掌握顺序表的存储结构形式及其描述和基本运算的实现。

5、熟练掌握动态链表结构及有关算法的设计二、实验内容题目一:顺序表的基本操作[问题描述]实现顺序表的建立、求长度,取元素、修改元素、插入、删除等顺序表的基本操作。

[基本要求](1)依次从键盘读入数据,建立带头结点的顺序表;(2)输出顺序表中的数据元素(3)求顺序表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。

(6)根据算法,将两个有序的顺序表合并成一个有序顺序表。

[测试数据] 由学生任意指定。

题目二:单链表的基本操作[问题描述]实现带头结点的单链表的建立、求长度,取元素、修改元素、插入、删除等单链表的基本操作。

[基本要求](1)依次从键盘读入数据,建立带头结点的单链表;(2)输出单链表中的数据元素(3)求单链表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。

(6)根据算法,将两个有序的单链表合并成一个有序单链表。

[测试数据]由学生任意指定。

三、源代码(一)顺序表的基本操作#include<iostream>using namespace std;#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;typedef int ElemType;#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct { //结构体ElemType *elem;int length;int listsize;}SqList;SqList Lx;Status InitList_Sq(SqList &L) //分配空间{ L.elem=new ElemType[LIST_INIT_SIZE];if(!L.elem)exit(OVERFLOW);L.length =0;L.listsize=LIST_INIT_SIZE;return OK;}Status ListInsert(SqList &L,int i,ElemType e) //插入新元素{ int *q,*p;ElemType *newbase;if(i<1 || i>L.length+1) return ERROR;if(L.length>=L.listsize){ newbase=new ElemType[L.listsize+LISTINCREMENT];if(!newbase) exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}q=&(L.elem[i-1]);for (p=&(L.elem[L.length-1]);p>=q;--p)*(p+1)=*p;*q=e;++L.length;return OK;}Status Listlength(SqList L) //长度{ int *p=L.elem; //判断线形表是否存在while(p){ return (L.length); }}Status GetElem(SqList L, int i,ElemType &e) //取元素{ if(i<1 || i>L.length)return ERROR;else{ e=L.elem[i-1];return e;}}void MergeList(SqList La,SqList Lb,SqList &Lc) //合并{ ElemType ai,bj;InitList_Sq(Lc);int i=1,j=1,k=0;int La_len,Lb_len;La_len=Listlength(La);Lb_len=Listlength(Lb);while((i<=La_len)&&(j<=Lb_len)){ GetElem(La,i,ai);GetElem(Lb,j,bj);if(ai<=bj){ ListInsert(Lc,++k,ai);++i; }else{ ListInsert(Lc,++k,bj);++j; }}while(i<=La_len){ GetElem(La,i++,ai);ListInsert(Lc,++k,ai);}while(j<=Lb_len){ GetElem(Lb,j++,bj);ListInsert(Lc,++k,bj);}}void show(SqList L,int i) //显示{ int j;ElemType k;cout<<"顺序表显示如下:"<<endl;for(j=0;j<i-1;j++){ k=L.elem[j];cout<<k<<"->"; }if(j==i-1 && i>0){ k=L.elem[j]; cout<<k; }cout<<endl;}void create(SqList &L,int n) //输入元素{ int e;for(int i=0;i<n;i++)L.elem[i]=e;L.length=i+1; }}Status ListDelete_Sq(SqList &L,int i,ElemType &e) //删除{ ElemType *p, *q;if(i<1 || i>L.length) return ERROR;p=&(L.elem[i-1]);e=*p;q=L.elem+L.length-1;for(++p;p<=q;++p) *(p-1)=*p;--L.length;return OK;}Status Listxiugei(SqList &L,int i,ElemType &e) //修改{ if(i<1 || i>L.length)return ERROR;else{ L.elem[i-1]=e;return OK; }}void shuru(SqList &L1) //顺序表的创建{ int a;InitList_Sq(L1);cout<<"请输入顺序表的长度:";cin>>a;cout<<"请输入顺序表的元素(共"<<a<<"个)"<<endl;create(L1,a);show(L1,a);}void chaxun(SqList &L1) //取第i个位置的元素{ int j;ElemType e1;cout<<"请选择所要取出元素的位置:";while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>j; }GetElem(L1,j,e1);cout<<"取出的元素为:"<<e1<<endl; }void xiugai(SqList &L1) //修改第i个位置的元素{ int a;int j; ElemType e1;a=L1.length;cout<<"请选择所要修改元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要修改元素的位置:";cin>>j; }cout<<"要修改成的元素:";cin>>e1;Listxiugei(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a);}void shanchu(SqList &L1) //删除顺序表里的元素{ int a;int j; ElemType e1;a=L1.length;cout<<"请选择所要删除元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>j; }ListDelete_Sq(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a-1);}void charu(SqList &L1) //插入元素到顺序表里{ int a; int j; ElemType e1;a=L1.length;cout<<"请选择所要插入元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>j; }cout<<"要插入的元素:";cin>>e1;ListInsert(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a+1);}void hebing(SqList &L3) //合并两个顺序表{ SqList L1,L2;int a,b;InitList_Sq(L1); InitList_Sq(L2);cout<<"请输入第一个有序表的长度:"; cin>>a;cout<<"请输入第一个有序表的元素(共"<<a<<"个)"<<endl;create(L1,a);show(L1,a);cout<<"请输入第二个有序表的长度:"; cin>>b;cout<<"请输入第二个有序表的元素(共"<<b<<"个)"<<endl;create(L2,b);show(L2,b);MergeList(L1,L2,L3);cout<<"合并后的有序表如下:"; show(L3,a+b);}void main() //主菜单{ int choice;for(;;){ cout<<" 顺序表的基本操作"<<endl;cout<<" 1.顺序表的创建"<<endl;cout<<" 2.顺序表的显示"<<endl;cout<<" 3.顺序表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到顺序表里"<<endl;cout<<" 7.删除顺序表里的元素"<<endl;cout<<" 8.合并两个顺序表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择:";cin>>choice;switch(choice){ case 1: shuru(Lx);break;case 2: show(Lx,Lx.length);break;case 3: cout<<"顺序表的长度:"<<Listlength(Lx)<<endl;break; case 4: chaxun(Lx);break;case 5: xiugai(Lx);break;case 6: charu(Lx);break;case 7: shanchu(Lx);break;case 8: hebing(Lx);break;case 9: cout<<"退出系统!"<<endl;exit(0);break;default : cout<<"输入有误,请重新选择"<<endl;break; }}}(二)单链表的基本操作#include<iostream>using namespace std;#define true 1#define false 0#define ok 1#define error 0#define overflow -2typedef int Status;typedef int ElemType;typedef struct LNode //存储结构{ ElemType data;struct LNode *next;}LNode,*LinkList;void CreateList(LinkList &L,int n) //尾插法创建单链表{ LinkList p;L=new LNode;L->next=NULL; //建立一个带头结点的单链表LinkList q=L; //使q指向表尾for(int i=1;i<=n;i++){ p=new LNode;cin>>p->data;p->next=NULL;q->next=p;q=p; }}Status GetElem(LinkList L,int i,ElemType &e)//取第i个元素{ LinkList p=L->next;int j=1;while(p&&j<i){ p=p->next;++j; }if(!p||j>i) return error; //第i个元素不存在 e=p->data;return ok;}Status LinkInsert(LinkList &L,int i,ElemType e) //插入{ LinkList p=L;int j=0;while(p&&j<i-1){ p=p->next;++j; } //寻找第i-1个结点 if(!p||j>i-1)return error; //i小于1或者大于表长加1 LinkList s=new LNode; //生成新结点s->data=e;s->next=p->next; //插入L中p->next=s;return ok;}Status ListDelete(LinkList &L,int i,ElemType &e) // 删除{ LinkList p=L;LinkList q;int j=0;while(p->next&&j<i-1){ //寻找第i个结点,并令p指向其前驱p=p->next;++j; }if(!(p->next)||j>i-1) return error; //删除位置不合理q=p->next;p->next=q->next; //删除并释放结点e=q->data;delete(q);return ok;}void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc) { //合并两个顺序链表LinkList pa,pc,pb;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){ if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next; }else{ pc->next=pb;pc=pb;pb=pb->next; }}pc->next=pa?pa:pb;delete(Lb);}void show(LinkList L) //显示{ LinkList p;p=L->next;while(p){ cout<<p->data<<"-->";p=p->next; }cout<<endl;}int Length(LinkList L,int i) //表长{ i=0;LinkList p=L->next;while(p){ ++i;p=p->next; }return i;}void xiugai(LinkList L) //修改{ int i,j=1;ElemType k;ElemType e,m;LinkList p=L->next;cout<<"请输入要修改的元素位置(0<i<length):";cin>>i;GetElem(L,i,e);cout<<"该位置的元素:"<<e<<endl;cout<<"修改后的元素值:";cin>>k;while(p&&j<i){ p=p->next;++j; }m=p->data;p->data=k;cout<<"修改后的单链表显示如下:"<<endl;show(L);}void hebing() //合并两个单链表{ int a,b;LinkList La,Lb,Lc;cout<<"请输入第一个有序链表的长度:"<<endl;cin>>a;cout<<"请输入第一个有序链表的元素共("<<a<<"个):"<<endl;CreateList(La,a);show(La);cout<<"请输入第二个有序链表的长度:"<<endl;cin>>b;cout<<"请输入第二个有序链表的元素共("<<b<<"个):"<<endl;CreateList(Lb,b);show (Lb);MergeList(La,Lb,Lc);cout<<"合并后的有序链表如下:"<<endl;show(Lc);}void main() //主函数{ int select;int x;ElemType y;LinkList list;for(;;){ cout<<" 单链表的基本操作"<<endl;cout<<" 1.单链表的创建"<<endl;cout<<" 2.单链表的显示"<<endl;cout<<" 3.单链表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到单链表里"<<endl;cout<<" 7.删除单链表里的元素"<<endl;cout<<" 8.合并两个单链表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择:";cin>>select;switch(select){ case 1:cout<<"请输入单链表的长度:"<<endl;cin>>x;cout<<"请输入"<<x<<"个元素"<<endl;CreateList(list,x);break;case 2: cout<<"单链表显示如下:"<<endl;show(list);break;case 3: int s;cout<<"单链表的长度为:"<<Length(list,s)<<endl;break;case 4: cout<<"请选择所要取出元素的位置:";while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>x; }GetElem(list,x,y);cout<<"该位置的元素为:"<<y<<endl;break;case 5: xiugai(list); break;case 6: cout<<"请选择要插入的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>x; }cout<<"要插入的元素值:";cin>>y;LinkInsert( list,x,y);cout<<"插入后单链表显示如下:"<<endl;show(list);break;case 7: cout<<"请选择要删除的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误,请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>x; }ListDelete(list,x,y);cout<<"要删除的元素值:"<<y<<endl;cout<<"删除后的单链表显示如下:"<<endl;show(list);break;case 8: hebing();break;case 9: exit(0);default : cout<<"输入有误,请重新输入"<<endl;break;}}}四、测试结果1)顺序表的测试结果2)单链表的测试结果五、心得体会当听到老师说写数据结构实验报告时,我有点惊讶,才学了不到一个月,就要写实验报告。

编写带头结点的单链表中统计结点个数的算法。

编写带头结点的单链表中统计结点个数的算法。

编写带头结点的单链表中统计结点个数的算法。

以下是带头结点的单链表统计结点个数的算法:
1. 首先定义一个指针变量p指向链表的第一个结点。

2. 在循环中遍历整个链表,计算每个结点的个数。

在遍历过程中,将当前结点的值赋给变量num。

3. 将当前结点的指针移动到下一个结点,继续循环。

4. 如果当前结点没有对应的下一个结点,则返回结点个数的值。

5. 如果当前结点有对应的下一个结点,则将当前结点的值和下
一个结点的指针合并计算结点个数的值。

下面是实现该算法的C语言代码:
```
int count = 0; // 结点个数
int* ptr; // 指向链表的第一个结点的指针
void dfs(int node) {
ptr = node; // 将当前结点的指针指向链表的第一个结点
count++; // 计算当前结点的个数
}
int main() {
单链表头结点为*head, *p;
p = head; // 指向链表的第一个结点
int num = 0; // 用于记录每个结点的个数
dfs(p); // 遍历整个链表并计算结点个数
return 0;
}
```
该算法的时间复杂度为O(n),空间复杂度为O(n)。

其中,n是链表的结点数。

数据结构c++顺序表、单链表的基本操作,查找、排序代码

数据结构c++顺序表、单链表的基本操作,查找、排序代码

} return 0; }
实验三 查找
实验名称: 实验3 查找 实验目的:掌握顺序表和有序表的查找方法及算法实现;掌握二叉排序 树和哈希表的构造和查找方法。通过上机操作,理解如何科学地组织信 息存储,并选择高效的查找算法。 实验内容:(2选1)内容1: 基本查找算法;内容2: 哈希表设计。 实验要求:1)在C++系统中编程实现;2)选择合适的数据结构实现查 找算法;3)写出算法设计的基本原理或画出流程图;4)算法实现代码 简洁明了;关键语句要有注释;5)给出调试和测试结果;6)完成实验 报告。 实验步骤: (1)算法设计 a.构造哈希函数的方法很多,常用的有(1)直接定址法(2)数字分析法;(3) 平方取中法;(4)折叠法;( 5)除留余数法;(6)随机数法;本实验采用的是除 留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈 希地址 (2)算法实现 hash hashlist[n]; void listname(){ char *f; int s0,r,i; NameList[0].py="baojie"; NameList[1].py="chengቤተ መጻሕፍቲ ባይዱoyang"; ……………………………… NameList[29].py="wurenke"; for(i=0;i<q;i++){s0=0;f=NameList[i].py; for(r=0;*(f+r)!='\0';r++) s0+=*(f+r);NameList[i].k=s0; }} void creathash(){int i;
v[k-1]=v[k]; nn=nn-1; return ; } int main() {sq_LList<double>s1(100); cout<<"第一次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); s1.ins_sq_LList(0,1.5); s1.ins_sq_LList(1,2.5); s1.ins_sq_LList(4,3.5); cout<<"第二次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); s1.del_sq_LList(0); s1.del_sq_LList(2); cout<<"第三次输出顺序表对象s1:"<<endl; s1.prt_sq_LList(); return 0; } 运行及结果:

c语言单链表头插法

c语言单链表头插法

c语言单链表头插法单链表是一种常见的数据结构,是一种线性表,是由一系列节点组成的,每个节点都包含一个数据和一个指向下一个节点的指针。

在C语言中,我们可以使用结构体来定义一个节点,例如:```cstruct Node {int data;struct Node* next;};```上述代码定义了一个名为Node的结构体,它包含两个成员,一个是整型的数据data,另一个是指向下一个节点的指针next。

在使用单链表头插法创建链表时,我们首先需要定义一个头节点,它不存储任何数据,仅用作链表的标记。

然后,我们可以通过以下步骤来插入新的节点:1. 创建一个新节点,并为其分配内存空间。

```cstruct Node* newNode = (struct Node*)malloc(sizeof(struct Node));```上述代码使用malloc函数为新节点分配内存空间。

2. 将新节点的数据赋值。

```cnewNode->data = value;```上述代码将新节点的data成员设置为value。

3. 将新节点的next指针指向头节点的next指针所指向的节点。

```cnewNode->next = head->next;```上述代码将新节点的next指针指向头节点的next指针指向的节点,即将新节点插入到头节点之后。

4. 将头节点的next指针指向新节点。

```chead->next = newNode;```上述代码将头节点的next指针指向新节点,即将新节点设置为链表的第一个节点。

完整的头插法创建链表的函数如下:```cstruct Node* createList(int values[], int n) {struct Node* head = (struct Node*)malloc(sizeof(struct Node));head->next = NULL;for (int i = 0; i < n; i++) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));newNode->data = values[i];newNode->next = head->next;}return head;}```上述代码中的createList函数接受一个整型数组values和一个整数n作为参数,返回一个头指针。

数据结构链表简单程序代码

数据结构链表简单程序代码
printf("逆置后的链表为:");//显示逆置后的链表
display(L);
printf("\n");
insert(&L,2,6);//在第2个位置插入元素6
printf("在第2个位置插入6后的链表为:");//显示插入元素后的链表
display(L);
printf("\n");
q->next=L->next;// 在表头节点
L->next=q; // 后插入节点,且每次插入的都是后移后的节点
}
}
//链表长度函数
int length(Lnode L)
{
return L.len;
}
//插入元素函数
void insert(Lnode *L,int i,elemtype x)
}
creatlist(&L);//创建空链表
for(i=0;i<n;i++)//把元素放入链表
{
putlist(&L,a[i]);
}
printf("数入链表为:");//显示输入的链表
display(L);
printf("\n");
converse(&L);//逆置链表
{
j++;
if(j==i+1)break;//因为有头结点,所以是i+1
p=p->next;
}
return p->data;//返回第i个元素的值
}
//删除元素函数

数据结构学习-带头结点的单链表就地逆置

数据结构学习-带头结点的单链表就地逆置

数据结构学习-带头结点的单链表就地逆置所谓“就地是指辅助空间复杂度为O(1)。

解法⼀:将头结点摘下,然后从第⼀结点开始,依次前插⼊到头结点的后⾯(头插法),直到最后⼀个结点为⽌。

代码如下解法⼆:通过若⼲操作将指针反转达到逆置的⽬的。

假设pre、p和r指向3个相邻的结点,如上图。

*pre之前的结点的指针都已经调整完毕,它们的next指针都指向其原前驱结点。

现在令*p结点的next域指向*pre结点,注意到⼀旦调整指针的指向后,*p的后继结点的链就断开了,为此⽤r来指向原*p结点的后继结点。

处理第⼀个结点时,将其next域置为NULL,。

处理最后⼀个结点后,将头结点的指针指向它。

代码:LinkList Reverse (LinkList L){ LNode *p,*r;//p 为⼯作指针,r 为p 的后继以防断链 p=L->next;//从第⼀个元素结点开始 L->next=NULL;//先将头结点L 的next 域置为NULL while (p!=NULL)//依次将元素结点摘下 { r =p->next;//暂存p 的后继 p->next=L->next;//将p 结点插⼊到头结点之后 L->next=p; p =r; } return L;}Linklist reserve(LinkList L){ LNode *pre,*p=L->next,*r=p->next; p ->next=NULL;//处理第⼀个结点 while (r!=NULL)//r 为空,则说明p 为最后⼀个结点 { pre =p;//依次遍历 p=r; r =r->next; p ->next=pre;//指针反转 } L->next=p;//处理最后⼀个结点 return L;}。

单链表的基本操作代码

单链表的基本操作代码

单链表的基本操作代码单链表是一种常用的数据结构,它具有优秀的插入和删除性能,在数据存储和处理方面具有广泛的应用。

单链表的基本操作包含创建链表、插入节点、删除节点、查找节点等,下面是单链表的基本操作代码:1. 定义单链表结构体:typedef struct ListNode {int val;struct ListNode *next;} ListNode;2. 创建单链表:ListNode *createList(int arr[], int n) {ListNode *head = NULL, *tail = NULL, *p = NULL;for(int i = 0; i < n; i++) {p = (ListNode *)malloc(sizeof(ListNode));p->val = arr[i];p->next = NULL;if(head == NULL) {head = tail = p;} else {tail->next = p;tail = p;}}return head;}3. 插入节点:void insertNode(ListNode **head, int val, int pos) {ListNode *p = (ListNode *)malloc(sizeof(ListNode)); p->val = val;p->next = NULL;if(*head == NULL) {if(pos != 0) {printf("Invalid position\n");return;} else {*head = p;return;}}if(pos == 0) {p->next = *head;*head = p;} else {int i = 0;ListNode *q = *head;while(q != NULL && i < pos - 1) {q = q->next;i++;}if(q == NULL || i != pos - 1) {printf("Invalid position\n");return;}p->next = q->next;q->next = p;}}4. 删除节点:void deleteNode(ListNode **head, int pos) {if(*head == NULL) {printf("List is empty\n");return;}if(pos == 0) {ListNode *p = *head;*head = (*head)->next;free(p);} else {int i = 0;ListNode *p = *head, *q = NULL; while(p != NULL && i < pos) { q = p;p = p->next;i++;}if(p == NULL || i != pos) {printf("Invalid position\n");return;}q->next = p->next;free(p);}}5. 查找节点:ListNode *findNode(ListNode *head, int val) {ListNode *p = head;while(p != NULL) {if(p->val == val) {return p;}p = p->next;}return NULL;}单链表的基本操作是数据结构中最基础的部分,掌握好这些代码对于往后的学习和应用都会有很大的帮助。

数据结构 实验二:单链表的基本操作

数据结构 实验二:单链表的基本操作

数据结构实验二:单链表的基本操作数据结构实验二:单链表的基本操作实验二:单链表的基本操作一、【实验目的】1、理解和掌握单链表的类型定义方法和结点生成方法。

2、掌握建立单链表和显示单链表元素的算法。

3、掌握单链表的查找、插入和删除算法二、【实验内容】1、建立一个整形数的单链表,手动输入10个数,并从屏幕显示单链表元素列表。

2、从键盘输入一个数,查找在以上创建的单链表中是否存在该数;如果存在,显示它的位置;如果不存在,给出相应提示。

3、删除上述单链表中指定位置的元素。

以下就是程序部分代码,恳请调试并补足并使之恰当运转:1.linlist.htypedefstructnode{datatypedata;structnode*next;}slnode;voidlistinitiate(slnode**head)/*初始化*/{/*如果有内存空间,申请头结点空间并使头指针head指向头结点*/if((*head=(slnode*)malloc(sizeof(slnode)))==null)exit(1);(*head)->next=null;/*置链尾标记null*/}intlistlength(slnode*head){slnode*p=head;/*p指向首元结点*/intsize=0;/*size初始为0*/while(p->next!=null)/*循环计数*/{p=p->next;size++;}returnsize;}intlistinsert(slnode*head,inti,datatypex)/*在带头结点的单链表head的数据元素ai(0≤i≤size)结点前*//*填入一个存放数据元素x的结点*/{slnode*p,*q;intj;p=head;/*p指向首元结点*/j=-1;/*j起始为-1*/while(p->next!=null&&j<i-1)/*最终让指针p指向数据元素ai-1结点*/{p=p->next;j++;}if(j!=i-1){printf(\填入边线参数弄错!\return0;}/*生成新结点由指针q指示*/if((q=(slnode*)malloc(sizeof(slnode)))==null)exit(1);q->data=x;q->next=p->next;/*给指针q->next赋值*/p->next=q;/*给指针p->next重新赋值*/return1;}intlistdelete(slnode*head,inti,datatype*x)/*删除带头结点的单链表head的数据元素ai(0≤i≤size-1)结点*//*删除结点的数据元素域值由x带回。

带结点与不带结点用头插法和尾插法创建单链表

带结点与不带结点用头插法和尾插法创建单链表

带结点与不带结点⽤头插法和尾插法创建单链表⼀、采⽤带有头结点的头插法逆向建⽴单链表Linklist List_HeadInsert1(LinkList &L) //采⽤带有头结点的头插法逆向建⽴单链表{LNode *s; //声明⼀个临时结点int x;L=(LinkList)malloc(sizeof(LNode)); //创建头结点L->next=NULL; //初始为空链表scanf("%d",&x); //输⼊结点的值while(x!=9999){s=(LNode*)malloc(sizeof(LNode)); //创建新结点s->data=x;s->next=L->next; //将新结点插⼊表中,L为头指针L->next=s;scanf("%d",&x);}return L;}⼆、采⽤不带有头结点的头插法逆向建⽴单链表Linklist List_HeadInsert2(LinkList &L) //采⽤不带有头结点的头插法逆向建⽴单链表{LNode *s; //声明⼀个临时结点int x;L=NULL;scanf("%d",&x); //输⼊结点的值while(x!=9999){s=(LNode*)malloc(sizeof(LNode)); //创建新结点s->data=x;if(L==NULL) // 若第⼀次创建节点,则将该点设置为头节点{L=s;s->next=NULL;}else{ // 若不是第⼀次创建节点,则直接将新节点接到链表头s->next=L;L=s;}scanf("%d",&x);}return L;}三、采⽤带有头结点的尾插法正向建⽴单链表Linklist List_TailInsert1(LinkList &L) //采⽤带有头结点的尾插法正向建⽴单链表{LNode *s,*r; //s为临时结点,r为表尾指针int x;L=(LinkList)malloc(sizeof(LNode)); //创建头结点L->next=NULL; //初始为空链表r=L;scanf("%d",&x); //输⼊结点的值while(x!=9999){s=(LNode*)malloc(sizeof(LNode)); //创建新结点s->data=x;r->next=s;r=s; //r指向新的表尾结点scanf("%d",&x);}r->next=NULL; //尾结点指针为空return L;}四、⽤不带有头结点的尾插法正向建⽴单链表Linklist List_TailInsert2(LinkList &L) //采⽤不带有头结点的尾插法正向建⽴单链表{LNode *s,*r; //s为临时结点,r为表尾指针int x;L=NULL;r=L;scanf("%d",&x); //输⼊结点的值while(x!=9999){s=(LNode*)malloc(sizeof(LNode)); //创建新结点s->data=x;if(L==NULL) // 创建链表的第⼀个节点{L=s;r=s;s->next=NULL;}else{r->next=s;r=s;}scanf("%d",&x);}r->next=NULL; //尾结点指针为空return L;}。

PTA带头结点的链式表操作集

PTA带头结点的链式表操作集

PTA带头结点的链式表操作集6-2 带头结点的链式表操作集 (20 分)本题要求实现带头结点的链式表操作集。

函数接⼝定义:List MakeEmpty();Position Find( List L, ElementType X );bool Insert( List L, ElementType X, Position P );bool Delete( List L, Position P );其中List结构定义如下:typedef struct LNode *PtrToLNode;struct LNode {ElementType Data;PtrToLNode Next;};typedef PtrToLNode Position;typedef PtrToLNode List;各个操作函数的定义为:List MakeEmpty():创建并返回⼀个空的线性表;Position Find( List L, ElementType X ):返回线性表中X的位置。

若找不到则返回ERROR;bool Insert( List L, ElementType X, Position P ):将X插⼊在位置P指向的结点之前,返回true。

如果参数P指向⾮法位置,则打印“Wrong Position for Insertion”,返回false;bool Delete( List L, Position P ):将位置P的元素删除并返回true。

若参数P指向⾮法位置,则打印“Wrong Position for Deletion”并返回false。

裁判测试程序样例:#include <stdio.h>#include <stdlib.h>#define ERROR NULLtypedef enum {false, true} bool;typedef int ElementType;typedef struct LNode *PtrToLNode;struct LNode {ElementType Data;PtrToLNode Next;};typedef PtrToLNode Position;typedef PtrToLNode List;List MakeEmpty();Position Find( List L, ElementType X );bool Insert( List L, ElementType X, Position P );bool Delete( List L, Position P );int main(){List L;ElementType X;Position P;int N;bool flag;L = MakeEmpty();scanf("%d", &N);while ( N-- ) {scanf("%d", &X);flag = Insert(L, X, L->Next);if ( flag==false ) printf("Wrong Answer\n");}scanf("%d", &N);while ( N-- ) {scanf("%d", &X);P = Find(L, X);if ( P == ERROR )printf("Finding Error: %d is not in.\n", X);else {flag = Delete(L, P);printf("%d is found and deleted.\n", X);if ( flag==false )printf("Wrong Answer.\n");}}flag = Insert(L, X, NULL);if ( flag==false ) printf("Wrong Answer\n");elseprintf("%d is inserted as the last element.\n", X);P = (Position)malloc(sizeof(struct LNode));flag = Insert(L, X, P);if ( flag==true ) printf("Wrong Answer\n");flag = Delete(L, P);if ( flag==true ) printf("Wrong Answer\n");for ( P=L->Next; P; P = P->Next ) printf("%d ", P->Data);return 0;}/* 你的代码将被嵌在这⾥ */输⼊样例:612 2 4 87 10 242 12 87 5输出样例:2 is found and deleted.12 is found and deleted.87 is found and deleted.Finding Error: 5 is not in.5 is inserted as the last element.Wrong Position for InsertionWrong Position for Deletion10 4 2 51 List MakeEmpty(){2 List l=(List)malloc(sizeof(struct LNode));3 l->Data=0;4 l->Next=NULL;5return l;6 }78 Position Find( List L, ElementType X ){9 Position p=(Position)malloc(sizeof(Position));10while(L){11if(L->Data==X){12 p=L;13return p;14 }15 L=L->Next;16 }17return ERROR;18 }//返回线性表中X的位置。

单链表的实现及其基本操作

单链表的实现及其基本操作

单链表的实现及其基本操作结点的引⼊链表是⼀种链式存储结构,链式存储结构的特点是⽤⼀组任意的存储单元存储数据元素。

为了能正确表⽰数据元素之间的线性关系,需引⼊结点概念。

⼀个结点表⽰链表中的⼀个数据元素,节点中除了储存数据元素的信息,还必须存放指向下⼀个节点的的指针(单、双链表的最后⼀个节点除外,它们存储的是⼀个空指针NULL)结点的结构如下图所⽰:代码如下:1 typedef struct node{2int data;3struct node* pNext;4 }Node, *PNode;View Code注:这⾥假设结点中储存的是整型 (int) 的数据单链表由多个结点依次连接⽽成,我们不难想象出它结构:我们注意到:在第⼀个结点的前⾯多了⼀个头结点,这是为了处理空表的⽅便⽽引⼊的,它的指针指向链表的第⼀个结点,⽽它的data域不存放任何信息。

单链表的基本操作1.创建链表1 PNode createList()2 {3int len, value;45 PNode pHead = (PNode)(malloc(sizeof(Node)));6 PNode pTail = pHead;7 pTail->pNext = NULL;89 printf("请输⼊你要的节点个数:");10 scanf("%d", &len);11for(int i=1;i<=len;i++){12 printf("请输⼊第%d个节点的值:", i);13 scanf("%d", &value);1415 PNode pNew = (PNode)malloc(sizeof(Node));16 pNew->data = value;17 pTail->pNext = pNew;18 pTail = pNew;19 pTail->pNext = NULL;20 }2122return pHead;23 }View Code2.遍历链表void traverse(PNode pHead){printf("遍历结果为:\n");PNode pTra = pHead;while(pTra->pNext != NULL){printf("%d ", pTra->pNext->data);pTra = pTra->pNext;}printf("\n");}View Code3.判断链表是否为空1bool isEmpty(PNode pHead)2 {3if(pHead->pNext==NULL)4return true;5else6return false;7 }View Code4.链表长度1int length(PNode pHead)2 {3int len = 0;4while(pHead->pNext!=NULL){5 pHead = pHead->pNext;6 len++;7 }8return len;910 }View Code5.插⼊结点1bool insert(PNode pHead, int pos, int val)2 {3if(pos<1 || pos>length(pHead)){4return false;5 }else{6 PNode pInsert = pHead;7for(int i=1;i<pos;i++){8 pInsert = pInsert->pNext;9 }1011 PNode pNew = (PNode)malloc(sizeof(Node));12 pNew->data = val;13 pNew->pNext = pInsert->pNext;14 pInsert->pNext = pNew;1516return true;17 }1819 }View Code6.删除结点1bool del(PNode pHead, int pos)2 {3if(pos<1 || pos>length(pHead)){4return false;5 }else{6 PNode pDel = pHead;7for(int i=1;i<pos;i++){8 pDel = pDel->pNext;9 }1011if(pos==length(pHead)){12free(pDel->pNext);13 pDel->pNext = NULL;14 }else{15 PNode pNext = pDel->pNext->pNext;16free(pDel->pNext);17 pDel->pNext = pNext;18 }1920return true;2122 }232425 }View Code7.查找节点(1)按元素值查找1 PNode locate(PNode pHead, int value)2 {3 PNode p = pHead->pNext;4while(p&&p->data!=value){ //NULL 是 05 p = p->pNext;6 }7return p;8 }View Code(2)按序号查找1 PNode get(PNode pHead, int k)2 {3 PNode p = pHead;4for(int i=1;i<=k;i++){5 p = p->pNext;6 }7return p;89 }View Code完整代码1 #include<stdio.h>2 #include<stdlib.h>3 typedef struct node{4int data;5struct node* pNext;6 }Node, *PNode;78 PNode createList();9void traverse(PNode pHead);10bool isEmpty(PNode pHead);11int length(PNode pHead);12bool insert(PNode pHead, int pos, int val);13bool del(PNode pHead, int pos);14 PNode get(PNode pHead, int k); //按序号查找15 PNode locate(PNode pHead, int value);//按值查找 1617int main(void)18 {19//test2021return0;22 }2324 PNode createList()25 {26int len, value;2728 PNode pHead = (PNode)(malloc(sizeof(Node)));29 PNode pTail = pHead;30 pTail->pNext = NULL;3132 printf("请输⼊你要的节点个数:");33 scanf("%d", &len);34for(int i=1;i<=len;i++){35 printf("请输⼊第%d个节点的值:", i);36 scanf("%d", &value);3738 PNode pNew = (PNode)malloc(sizeof(Node));39 pNew->data = value;40 pTail->pNext = pNew;41 pTail = pNew;42 pTail->pNext = NULL;43 }4445return pHead;46 }474849void traverse(PNode pHead)50 {51 printf("遍历结果为:\n");52 PNode pTra = pHead;53while(pTra->pNext != NULL)54 {55 printf("%d ", pTra->pNext->data);56 pTra = pTra->pNext;57 }58 printf("\n");59 }6061bool isEmpty(PNode pHead)62 {63if(pHead->pNext==NULL)64return true;65else66return false;67 }6869int length(PNode pHead)70 {71int len = 0;72while(pHead->pNext!=NULL){73 pHead = pHead->pNext;74 len++;75 }76return len;7778 }7980bool insert(PNode pHead, int pos, int val)81 {82if(pos<1 || pos>length(pHead)){83return false;84 }else{85 PNode pInsert = pHead;86for(int i=1;i<pos;i++){87 pInsert = pInsert->pNext;88 }8990 PNode pNew = (PNode)malloc(sizeof(Node));91 pNew->data = val;92 pNew->pNext = pInsert->pNext;93 pInsert->pNext = pNew;9495return true;96 }9798 }99100bool del(PNode pHead, int pos)101 {102if(pos<1 || pos>length(pHead)){103return false;104 }else{105 PNode pDel = pHead;106for(int i=1;i<pos;i++){107 pDel = pDel->pNext;108 }109110if(pos==length(pHead)){111free(pDel->pNext);112 pDel->pNext = NULL;113 }else{114 PNode pNext = pDel->pNext->pNext;115free(pDel->pNext);116 pDel->pNext = pNext;117 }118119return true;120121 }122123124 }125126 PNode get(PNode pHead, int k)127 {128 PNode p = pHead;129for(int i=1;i<=k;i++){130 p = p->pNext;131 }132return p;133134 }135 PNode locate(PNode pHead, int value)136 {137 PNode p = pHead->pNext;138while(p&&p->data!=value){ //NULL 是 0 139 p = p->pNext;140 }141return p;142 }View Code。

单链表的类型定义与基本操作

单链表的类型定义与基本操作

• 基本思想
• 找到第i个结点 • 从单链表上摘除该结点(修改某些结点的指针域)
L
a1
… ai-1
× ai
ai+1

a NULL
n
L
a1
… ai-1
ai+1

a NULL
n
12
• 算法
void delete_lklist(lklist &l , int i)
{ lklist p,q;
p=find_lklist(l, i-1);
• C语言类型描述
typedef struct node{
datatype
data; /*数据元素类型*/
struct node *next; /*指针类型*/
} node, * lklist; /*结点类型*/
• node是结点类型 • lklist是指向node类型的指针
1
二、一些基本操作
1. 初始化 initiate_lklist(l)
else printf("不存在第i个结点");
}
13
}
return (j); }
3
3. 按序号查找 find_lklist(l, i) • 定义
• 查找单链表第i个元素,否则返回NULL
• 基本思想
• 从头指针出发,顺链域next逐个往下搜索,直到 找到第i个结点为止
4
• 算法
node *find_lklist(lklist l, int i)
{ lklist p=l;
e
ai

a1n0 NULL
• 算法
void insert_lklist(lklist &l , datatype x, int i)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*线性表抽象数据类型的带头结点单链表实现*/ #include <stdio.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define MAXSIZE 100
#define NULL 0
typedef int status;
typedef int elemtype;
typedef struct lnode{
elemtype data;
struct lnode *next;
}lnode,*linklist;
/*初始化*/
status initlist(linklist *l){
*l=(linklist)malloc(sizeof(lnode));
if(*l) {(*l)->next=NULL;
return OK;
}
else return OVERFLOW;
}
/*销毁*/
status destroylist(linklist *l){
linklist p;
while(*l){
p=*l;
*l=(*l)->next;
free(p);
}
return OK;
}
/*置空*/
status clearlist(linklist *l){
linklist p,q;
p=(*l)->next;
(*l)->next=NULL;
while(p){
q=p;
p=p->next;
free(q);
}
return OK;
}
/*求单链表长度*/
int listlength(linklist l){
linklist p;
int i=0;
p=l->next;
while(p){
i++;
p=p->next;
}
return i;
}
/*单链表空否*/
status listempty(linklist l){
if(l->next) return FALSE;
else return TRUE;
}
/*查找*/
int locateelem(linklist l,elemtype e){
int i=0;
linklist p;
p=l->next;
while(p){
i++;
if (p->data==e) return i;
p=p->next;
}
return 0;
}
/*读第i个元素*/
status getelem(linklist l,int i,elemtype *e){
int j=1;
linklist p;
p=l->next;
while(p&&(j<i)){
j++;
p=p->next;
}
if (!p|| (j>i)) return ERROR;
*e=p->data;
return OK;
}
/*求前驱元素*/
status priorelem(linklist l,elemtype cur_e,elemtype *pre_e){
linklist p,q;
if(l->next&&(l->next->data==cur_e)) return ERROR;
q=l->next;
p=q->next;
while(p&&(p->data!=cur_e)){
q=p;
p=p->next;
}
if(!p) return ERROR;
*pre_e=q->data;
return OK;
}
/*求后继元素*/
status nextelem(linklist l,elemtype cur_e,elemtype *next_e){ linklist p;
p=l->next;
while(p&&(p->data!=cur_e))
p=p->next;
if(!p) return ERROR;
*next_e=p->next->data;
return OK;
}
/*在第i个位置插入元素e*/
status listinsert(linklist *l,int i,elemtype e){
int j=0;
linklist p,s;
p=*l;
while(p &&j<i-1){
j++;
p=p->next;
}
if(!p||(j>i-1)) return ERROR;
s= (linklist) malloc (sizeof(lnode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
/*删除第i个元素*/
status listdelete(linklist *l, int i, elemtype *e) {
linklist p,q;
int j;
p=*l;
j=0;
while ( p->next&& j<i-1){
p=p->next;
++j;
}
if (!(p->next)||j>i-1) return ERROR;
q=p->next;
p->next=q->next;
*e=q->data;
free(q);
return OK;
}
/*遍历单链表*/
status listtraverse(linklist l){
linklist p;
p=l->next;
while(p){
printf("%d ",p->data);
p=p->next;
}
printf("\n");
return OK;
}
/*尾插法建立顺序单链表*/
status listcreate(linklist *l){
linklist p,r,s;
elemtype e;
p=(linklist)malloc(sizeof(lnode));
r=p;
printf("input data(end by -1):");
scanf("%d",&e);
while(e!=-1){
s=(linklist)malloc(sizeof(lnode)); s->data=e;
r->next=s;
r=s;
scanf("%d",&e);
}
r->next=NULL;
*l=p;
return OK;
}
/*主函数*/
main(){
linklist la,lb,lc;
int i;
elemtype e,pre_e,next_e;
listcreate(&la);
listtraverse(la);
printf("the length of the list is %d\n",listlength(la));
printf("input i and e for insert:");
scanf("%d %d",&i,&e);
if(listinsert(&la,i,e)) listtraverse(la);
else printf("i is error!\n");
printf("input i :");
scanf("%d",&i);
getelem(la,i,&e);
printf("the element is %d ,",e);
priorelem(la,e,&pre_e);
nextelem(la,e,&next_e);
printf("prior is %d,",pre_e);
printf("next is %d\n",next_e);
listdelete(&la,i,&e);
listtraverse(la);
}。

相关文档
最新文档