精华内容
下载资源
问答
  • 利用 KMP 算法求子串在主串中出现的次数.c
  • 主要为大家详细介绍了Java实现带头结点单链表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 首先,我们先来创建一个不带头结点循环链表。所谓循环链表就是最后一个节点的指针域不是指向空,而是指向第一个节点,这样就实现了循环。 下面直接看代码实现 LinkList create_linklist() { int len; //用来存储...

    首先,我们先来创建一个不带头结点的循环链表。所谓循环链表就是最后一个节点的指针域不是指向空,而是指向第一个节点,这样就实现了循环。

    下面直接看代码实现

    LinkList create_linklist()
    {
        int len; //用来存储节点的个数
        int i; //for循环中的循环变量
        int val; //用来存放节点的值域
    
        LinkList Ll = NULL; //Ll用来存储指向第一个节点的指针
        LinkList pre = NULL; //pre用来存储指向LNew指向节点的前驱节点的指针,初始指向第一个节点
    
        //请求用户输入节点个数
        printf("请输入节点的个数:\n");
        scanf("%d", &len);
    
        for (i = 0; i < len; i++)
        {
            //每循环一次生成一个新的节点
            LinkList LNew = (LinkList)malloc(sizeof(LNode));
    
            //判断是否分配成功
            if(!LNew)
            {
                printf("动态内存分配失败,程序退出!\n");
                exit(-1);
            }
    
            //请求用户输入新节点的值
            printf("请输入第%d个节点的值\n", i+1);
            scanf("%d", &val);
    
            //i = 0时,即循环第一次运行时(生成第一个节点时)
            if(0 == i)
            {
                //将指向第一个节点的指针保存在Ll中,便于后续操作
                Ll = LNew;
    
                //初始化pre,使其指向第一个节点
                pre = Ll;
            }
    
            //将用户输入的值存储到数据域
            LNew->data = val;
    
            //将原来的节点挂在新生成的节点上
            pre->pNext = LNew;
    
            //新节点变成当前的最后一个节点,需要将其指针域指向第一个节点,从而形成循环单链表
            LNew->pNext = Ll;
            
            //pre后移,使其始终指向LNew指向节点的前驱节点,便于进行将LNew指向节点的前驱节点(原来的节点)挂在LNew指向的节点(新生成的节点)上的操作
            pre = LNew;
        }
    
        //提示用户链表创建成功
        printf("链表创建成功!\n");
    
        //返回指向第一个节点的指针
        return Ll;   
    }

    接下来是求链表长度的操作

    int length_list(LinkList Ll)
    {   
        int len = 1; //用来存储链表长度,初始值为1
        LinkList p = Ll;
    
        //如果指向第一个节点的指针为空,链表长度为0
        if(!Ll)
            return 0;
    
        //如果p->pNext不指向第一个节点,表示p不是最后一个节点,则p后移一位,直到p->pNext指向第一个节点为止
        while(p->pNext != Ll)
        {
            //长度加一
            len++;
    
            //p后移一位
            p = p->pNext;
        }
    
        //返回链表长度
        return len;
    }
    

     下面是遍历输出的操作

    //不含头结点的循环单链表的遍历输出
    void show_linklist(LinkList Ll)
    {
        LinkList p = Ll;
    
        if(!Ll)
            return;
    
        while(true)
        {
            printf("%d ", p->data);
    
            p = p->pNext;
    
            if(p == Ll)
                break;
        }
    
        printf("\n");
    
        return;
    }

    最后是删除操作(其中删除第一个节点比较特别)

    void delete_node(LinkList * Ll, int pos) //Ll是指向第一个节点的指针的指针,pos是要删除节点的位置,最小值为1,最大值为链表长度
    {
        int i; //for中的循环变量
        LinkList p = * Ll;  //定义一个始终指向要删除节点的前驱节点的指针,初始指向第一个节点
    
        //判断链表是否为空
        if(!length_list(* Ll))
        {
            //提示用户链表为空
            printf("链表为空,无法删除!\n");
    
            //结束函数
            return;
        }
    
        //判断pos是否可执行
        if(pos < 1 || pos > length_list(* Ll))
        {
            //提示用户pos输入有误
            printf("删除位置过小或过大,无法删除\n");
    
            //结束函数
            return;
        }
    
        //如果删除的是第一个节点
        if(1 == pos)
        {
            //先通过for循环找到指向最后一个节点的指针(因为是循环链表,这里的最后一个节点,相当于第一个节点的前驱节点)
            for (i = 0; i < length_list(* Ll) - 1; i++)
            {
                p = p->pNext;
            }
    
            // 第一个节点的前驱节点挂在第一个节点的后驱节点上
            p->pNext = (* Ll)->pNext;
    
            //释放为一个节点分配的空间
            free(* Ll);
    
            //原来的第二个节点成为新的第一个节点(这一步是传值操作,这样以后才能找到这个链表)
            (* Ll) = p->pNext;
    
            //结束函数
            return;
        }
    
        //如果不是删除第一个节点,就要找到指向要删除节点的前驱节点的指针
        for(i = 1; i<pos-1; i++)
        {
            p = p->pNext;//p后移一位
        }
    
        //定义一个指向要删除节点的指针
        LinkList q = p->pNext;
    
        //将要删除节点的前驱节点挂在,要删除节点的后驱节点上
        p->pNext = q->pNext;
    
        //释放为要删除节点分配的空间
        free(q);
        q = NULL;
    
        //提示用户删除成功
        printf("删除成功!\n");
    
        //结束函数
        return;
    }

    展开全文
  • typedef struct LNode{ //定义单链表结点类型 ElemType data; //每个结点存放一个数据元素 struct LNode* next; //指针指向下一个结点 }LNode,*LinkList; //初始化一个空白的单链表 bool InitList(LinkList &...
    #include<stdio.h>
    
    #define ElemType int
    typedef struct LNode{  //定义单链表结点类型 
    	ElemType data;     //每个结点存放一个数据元素 
    	struct LNode* next; //指针指向下一个结点 
    }LNode,*LinkList;
    
    //初始化一个空白的单链表 
    bool InitList(LinkList &L)
    {
    	L=NULL;    //空表,暂时还没有存放任何结点(防止脏数据) 
    	return true;
    }
    
    bool Empty(LinkList L) //判断单链表是否为空 
    {
    	if(L==NULL)return true;
    	else return false;
    }
    
    int main()
    {
    	LinkList L;   //声明一个指向单链表的指针 
    	//初始化一个空表 
    	InitList(L);
    	
    	if(Empty(L))printf("此单链表为空!\n");
    	else printf("此单链表不空!\n");
    
    	return 0;
    } 
    
    展开全文
  • 不带头结点单链表

    2021-05-03 10:51:57
    单链表 线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。...typedef struct{ //定义单链表结点类型 ElemType data; //数据域 struct LNode *next; //指针域 }LNode,*LinkL

    不带头结点的单链表

    定义

     线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。为了建立元素间的线性关系,每个节点除了存放自身的信息外,还要存放一个指向下一个结点的指针。其结构图如下  
               | data| next|
    结点类型定义代码如下
    
    typedef struct{         //定义单链表结点类型
    ElemType data;          //数据域
    struct LNode *next;     //指针域
              }LNode,*LinkList;   
       //LNode:struct类型的别名,LNode*LinkList:指向链表的指针,相当于struct LNode *LinkList;
    

    初始化

    void InitList(LinkList *L){ 
     // 创建链表时要将改变值传回main函数,所以用引用类型的参数
         *L = NULL;
    
    }
    调用InitList(&head);
    方式二:
    void InitList(LNode *head){
        head=NULL;
    }
    
    

    判断是否是空表

    bool Empty(LinkList L) //判断链表是否为空 
    {
    	return (L==NULL);
    }
    

    求表长

    int GetLength(LinkList L) 
    {	
        int len = 0; 
    	if(L == NULL){
    		printf("空表");
    		return len;
    	 }
    	 LNode *p= &L;
    	 while(p != NULL){
    		p = p->next;
    		len++;
    	}      
    	return len;
    }
    

    打印表

    void PrintList(LinkList L)
    {  
       if(L==NULL) return;
       LNode *p = L;
       while(p){
       printf("%d-->",p->data);
       p = p->next;
       }
       printf("NULL\n");
    }
    

    查找

    按位查找结点

    LNode *GetElem(LinkList L,int i){
    	if(i == 1) return L;
    	if(i < 1) return NULL; 
    	int j = 0;
    	LNode *p = L;
    	while(p != NULL&& j<i){
    		p = p->next;
    		j++;
    	} 
    	return p;
    }
    

    按值查找结点

    LNode *GetElem(LinkList L,int e){
    	LNode *p =  L;
    	while(p && p->data != e)
    	p =p->next;
    	return p;
    } 
    

    插入

    指定结点的后插操作

    //指定结点的后插操作 
    bool InsertNextNode(LNode *p,int e){
    	if(p == NULL){
    		return false;
    	} 
    	LNode *s = malloc(sizeof(LNode));
    	if(s == NULL) {
    		return false; //分配空间失败 
    	}
    	s->data = e;
    	s->next = p->next;
    	p->next = s;
    	return true; 
    }
    

    在给定结点前插入

    将要插入的节点的数据与指定结点的数据交换,然后将这个新节点接在给定结点后

    bool InsertPrioNode(LNode *p,int e){
    	if(p==NULL){
    		return false;
    	}
    	LNode *s = malloc(sizeof(LNode));
    	s->data = p->data;
    	p->data = e;
    	s->next = p->next;
    	p->next = s;
    	return true;
    }
    

    按位序插入

    bool ListInsert(LinkList *L,int i,int e){
    	//*L表示指向第一个结点的 L的指针 
    	if(i<1){
    		return false;
    	}
    	if(i == 1)
    	{
    		LNode *s = malloc(sizeof(LNode));
    		s->data = e;
    		s->next = *L;
    		*L = s;
    		return true;
    	}
    	
    	LNode *p = GetElem(*L,i - 1); //获取前一个结点
    	InsertNextNode(p,e); 
    	return true;
    } 
    

    创表

    头插法

    void CreateListH(LinkList *L){
       LNode *t;         
         int a,n,i=0;
         printf("请输入表长:");
         scanf("%d",&n);
         while(i < a){
         	scanf("%d",&a);
         	t=(LNode *)malloc(sizeof(LNode));
            t->data=a;
            t->next=*L;
            *L = t;
    		 i++;
         }
    } 
    

    尾插法

    void CreatListT(LinkList *L){
         LNode *p,*t;         /*p工作指针,t临时指针*/
         int a,i=1;
         while(scanf("%d",&a)){
              if(a!=0){
                   t=(LNode *)malloc(sizeof(LNode));
                   t->data=a;
                   if(i==1){
                        *L=t;   
                   }
                   else{
                        p->next=t;
                   }
                   p=t;
    }
              else{   
                   p->next=NULL;
                   break;   
              }
              i++;
         }
    }
    

    删除

    删除给定结点

    bool DeleteList(LNode *p){
    	if(p==NULL) return false;
    	LNode *q = p->next;
    	p->data = q->data;
    	p->next = q->next;
    	free(q);
    	return true;
    } 
    

    按序位删除

    bool DeleteList(LinkList *L,int i,int *e){
    	LNode *p = GetElem(*L,i);
    	  DeleteList(p);
    	  return true;
    }
    

    销毁表

    void DestoryLinklist(LinkList *L){
      //摧毁链表 
        LinkList cur = *L;
        LinkList pre = NULL;
        if (*L == NULL){
            printf("链表为空");
            return ;
        }
        if (cur->next = NULL){
            *L = NULL;
            free(cur);
            cur = NULL;
            return ;
        }
        while(cur){
            pre = cur;
            cur = cur->next;
            free(pre);
            pre = NULL;
        }
    } 
    

    总结:不带头结点的遍历,增加结点等操作的循环判断条件都是 L != NULL,增删结点,创建链表,初始化等操作都需要用到函数值传递,所以函数的参数都用指针

    展开全文
  • 不带头结点单链表操作,包括插入、遍历、统计结点数等,要求写出数据结构算法思想及C语言实现函数 本文为博主原创文章,未经博主允许不得转载。 版权为陈博超所有,第一次于2021年06月22日发表于BLOG上 本BLOG...

    不带头结点的单链表操作,包括插入、遍历、统计结点数等,要求写出数据结构算法思想及C语言实现函数

    本文为博主原创文章,未经博主允许不得转载。
    版权为陈博超所有,第一次于2021年06月22日发表于BLOG上
    本BLOG上原创文章未经本人许可,不得用于商业用途。转载请经允许后注明出处,否则保留追究法律责任的权利。
    *
    算法如下:

    //不带头结点的单链表操作
    #include<stdio.h>
    #include<malloc.h>
    
    typedef int DataType;
    
    typedef struct Node
    {
    	DataType Data;
    	struct Node* next;
    }SLNode;
    
    //初始化
    void ListInitiate(SLNode** head)
    {
    	*head = NULL;
    }
    
    //求当前数据元素个数
    int ListLength(SLNode* head)
    {	SLNode* p;
    	int size = 0;
    	p = head;
    	while (p != NULL)
    	{
    		p = p->next;
    		size++;
    	}
    	return size;
    }
    
    //插入新结点
    int ListInsert(SLNode** head, int i, DataType x)
    {
    	SLNode* p, * q, * m;
    	int j;
    	if (i == 0)					//若在第0个位置插入
    	{
    		m = (SLNode*)malloc(sizeof(SLNode));
    		m->Data = x;
    
    		m->next = *head;
    		*head = m;
    		return 1;
    	}
    	else						//若不在第0个位置插入
    	{
    		p = *head;
    		j = 0;
    
    		while (p->next != NULL && j < i - 1)
    								//最终让指针p指向第i-1个结点	
    		{
    			p = p->next;
    			j++;
    		}
    		if (j != i - 1)
    		{
    			printf("插入元素位置参数错!");
    			return 0;
    		}
    		q = (SLNode*)malloc(sizeof(SLNode));
    		q->Data = x;
    
    		q->next = p->next;
    		p->next = q;
    		return 1;
    	}
    }
    
    //删除新结点
    int ListDelete(SLNode** head, int i, DataType* x)
    {
    	SLNode* p, * q, * m, *s;
    	int j;
    	if (i == 0)				//若在第0个位置删除
    	{
    		m = *head;			//让m指向第0个结点
    		*x = m->Data;		//把指针m所指的结点数据域值赋给x
    
    		*head = m->next;	//删除
    		free(m);			//释放m所指结点的内存空间
    		return 1;
    	}
    	else					//若不在第0个位置删除
    	{
    		p = *head;
    		j = 0;
    
    		while (p->next != NULL && p->next->next != NULL && j < i - 1)
    			//循环结束时指针p指向第i-1个结点
    		{
    			p = p->next;
    			j++;
    		}
    
    		if (j != i - 1)
    		{
    			printf("删除元素位置错误!");
    			return 0;
    		}
    
    		s = p->next;
    		*x = s->Data;
    		p->next = p->next->next;
    		free(s);
    		return 1;
    	}
    }
    
    //取数据元素
    int ListGet(SLNode* head, int i, DataType* x)
    {
    	SLNode* p;
    	int j;
    
    	p = head;
    	j = 0;
    
    	while (p->next != NULL && j < i)
    	{
    		p = p->next;
    		j++;
    	}
    	if (j != i)
    	{
    		printf("取数据元素位置错!");
    		return 0;
    	}
    
    	*x = p->Data;
    	return 1;
    }
    
    //撤销单链表
    void Destory(SLNode** head)
    {
    	SLNode* p, * q;
    	p = *head;
    
    	while (p != NULL)
    	{
    		q = p;
    		p = p->next;
    		free(q);
    	}
    	*head = NULL;
    }
    

    主函数如下:

    //不带头结点的单链表操作
    #include<stdio.h>
    #include<malloc.h>
    #include<Windows.h>
    typedef int DataType;
    #include"数据结构复习.h"
    
    
    int main()
    {
        SLNode* head;
        int i, x;
    
        ListInitiate(&head);            //初始化
        for (i = 0; i < 10; i++)        //插入10个数据元素
        {
            ListInsert(&head, i, i + 1);
        }
    
        ListDelete(&head, 4, &x);       //删除数据元素5
    
        for (i = 0; i < ListLength(head); i++)//显示当前数据元素
        {
            ListGet(head, i, &x);       //取元素
            printf("%d      ", x);      //显示
        }
        Destory(&head);                 ///撤销单链表
        system("pause");
        return 0;
    }
    
    

    运行截图如下:
    在这里插入图片描述

    码字不易,穷酸学生,各位老板打赏个1分钱支持一下,谢谢大家。
    在这里插入图片描述

    展开全文
  • 数据结构之不带头结点单链表

    千次阅读 2020-04-20 17:20:12
    那我们今天这篇博客就来说一下不带头结点单链表。 一、不带头结点单链表的定义 我们先来回忆一下带头结点的单链表是什么样子。如下图所示:红色的区域就是头结点,它有一个头指针指向它。 ...
  • key,如果等于,返回prev,循环结束后还没有找到就return false //删除第一次出现关键字为key的节点 public void romove(int key) {} 如果链表为空就说明里面没有元素,那就更可能删除其中任意一个元素;...
  • //不带头结点单链表 #include #include typedef struct LNode{ int data; struct LNode *next; }LNode,*LinkList; //不带头结点的:初始化一个空的单链表 bool InitList(LinkList &L){ L = NULL; return true...
  • 带头结点单链表

    2021-04-20 15:00:21
    带头结点单链表定义操作初始化结点前插后插查找插入删除求表长 定义 线性表的链式存储方式称为单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。 为了实现数据元素之间的线性关系,所以每个结点中...
  • C语言实现不带头结点单链表逆置的三种方法直接循环头插法递归法END! 直接循环 图片解释 ListNode* ReverseList1(ListNode *head) { if(head == NULL || head->next == NULL) { return head; } ...
  • 1.删除不带头结点单链表的第一个值为x的节点 #include"slnklist.h" linklist delx(linklist head, datatype x) { linklist p,pre; if (!head) { printf("链表为空!\n"); } p = head; pre = NULL; ...
  • C语言 不带头结点循环单链表的实现和相关操作。 #include<stdio.h> #include<stdlib.h> typedef int DAT; typedef struct node { DAT data; struct node *next; }Node; void init_list(Node **pL)//...
  • class Node(object): """节点""" def __init__(self, elem): self.elem = elem self.next = None ...# 不带头节点的单链表 class SingleLinkList(object): """单链表""" def __init__(self, node...
  • 带头结点和不带头结点单链表注意的小细节 在写不带头结点单链表中发现了一个问题,这个问题在带头结点的单链表中也存在,那就是值传递的问题。 首先来看一下 #include&amp;amp;amp;lt;stdio.h&amp;amp;...
  • 也就是返回一个空的不带头结点的链表 当第一个数据合法时,循环输入,使用尾插法建立新结点后插,但是当我只输入了一个数这个程序就结束了,麻烦各位老师帮我看看是哪里出了问题 ...
  • 不带头结点单链表逆置问题

    千次阅读 2020-05-25 20:15:28
    经常能被单链表逆置给绕进去,此时把个人解释和代码放出,方便记忆 /** * 反转链表 * 迭代实现 * @param p * @return */ private ListNode reverseListByIter(ListNode p){ if(p == null || p.next == ...
  • 前言:用不带头结点单链表来实现链队列要比带头结点的单链表实现复杂一点,主要在初始化队列,入队时有一些区别。特别是在入队时,要根据入队的是不是第一个元素来进行讨论。 1、初始化队列,使队头指针front和...
  • 数据结构-基本算法-不带头结点循环链表(学生时代源码,调试可运行)
  • 利用c++实现不带头结点链表的基本操作实现,如逆序建立链表,插入、删除链表元素等。
  • L是一个带头结点单链表,函数ListReverse_L(LinkList &L)要求在新开辟节点的前提下将单链表中的元素进行逆置,如原单链表元素依次为1,2,3,4,则逆置后为4,3,2,1。 函数接口定义: void ListReverse_L...
  • 带头结点单链表合并成一个Lc,他的头结点可以从中任选一个 这里讲La的头结点赋值给Lc,再用三个指针变量来操作当前三个链表中的结点 pc指针指向新结点加入到链表中 移动指针,让pa指向下一结点 pa=pa->...
  • 带头结点单链表,将其翻转,输出。typedef struct lnode { int data; struct lnode *next;/*指针域*/ } lnode,*linklist; /**linklist表示struct lnode类型的指针;lnode是别名*/
  • 单链表有两种形式:带头结点的单链表不带头结点单链表。 关于单链表L的基本操作跟带头结点的单链表的基本操作稍有不同,特别的是在删除函数和插入函数中都加入了对第一个结点的判断,因为在插入和删除中第一个...
  • 代码如下,欢迎大佬指正。 #include<stdio.h> #include<stdlib.h> typedef struct LNode { int data; struct LNode* next; }Node,*Link; //将link链表分解,采用尾插法来保持...//处理奇结点偶节点
  • 带头结点循环单链表循环单链表简单理解头文件(.h)代码文件(.cpp)代码测试参考资料 循环单链表简单理解 前面复习了单链表,单链表的尾结点的特点是next域为NULL(空);而我们今天要复习的循环单链表,和单链表基本...
  • 带头结点单链表的实现(c语言)

    千次阅读 2020-09-14 09:59:17
    //这个程序是带头结点单链表的实现 /* 单链表链式存储结构 头指针与头结点的异同: 头指针: 1、头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针 2、无论链表是否为空,头指针均...
  • 不带头结点单链表代码实现

    千次阅读 2016-10-20 11:28:27
    不带头结点单链表代码实现
  • 带头结点单链表请参见: [C语言实现常用数据结构:带头结点单链表(第3篇)https://blog.csdn.net/qq_43351159/article/details/107840078 功能:输入数据个数和数据,逆序保存到顺序表,并逆序输出显示到屏幕。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,276
精华内容 2,910
关键字:

不带头结点循环单链表