精华内容
下载资源
问答
  • JAVA 循环双链表的建立 import java.util.Scanner; //循环双向链表的结点类 class DuLNode { private Object data;...正确...5、假使 A、B 是两个按结点值从小到大排列的线性链表,编写一个将这两个有序的线...

    JAVA 循环双链表的建立 import java.util.Scanner; //循环双向链表的结点类 class DuLNode { private Object data;// 存放结点值 前驱结点的引用 后继结点的......

    要求:根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。正确...

    5、假使 A、B 是两个按结点值从小到大排列的线性链表,编写一个将这两个有序的线性链 表归并为一个按结点值从小到大排列的线性链表 java 的函数。 先根次序......

    p->next=q->next->next 2、在一个头指针为 head 的带头结点单链表中,要向表头插入一个由指针 p 指向的结点,则应执行 【4】p->next=head->next; 、【......

    p->next=q->next->next 2、在一个头指针为 head 的带头结点单链表中,要向表头插入一个由指针 p 指向的结点,则 应执行 【4】p->next=head->next; 、......

    程序功能: 利用链表对非线性二叉树进行存储表示和访问。能够创建二叉树, 并且能够按前序遍历显示输出所创建的二叉树。 2. 程序特点:采用 java 面向对象语言,对......

    A.无头结点的双向链表 B.带尾指针的循环链表 C.无头结点的单链表 D.带头指针的循环链表 正确答案:B 如果在数据结构中每个数据元素只可能有一个直接前驱,但可以......

    42. 假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同...

    42. (13 分)假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,...

    8 2012 年全国硕士研究生入学统一考试—计算机专业基础综合试题 42.(13 分)假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,则可共享相同的后缀存储......

    在带头结点的双向循环链表中的 p 结点之后插入一个新结点 s,其修改链的 java 语句序列是( D )。 A. p.setNext(s); s.setPrior(p); p.getNext().set......

    18.对于一个头指针为 head 的带头结点的单链表,判定该表为空表的条件是__...

    1、编程实现单链表的建立、插入、删除和查找算法,语言采用 C 或 JAVA 等。 、编程实现单链表的建立、插入、删除和查找算法, /*P33 用头插法建立带头结点的单......

    值为 null //头指针 //构造空链表 //导入双链表结点类 //导入线性表接口 //带头结点的循环双链表类 } public E get(int index) { if (index>=0) { ......

    ( 个数据元素。 A. i B. n-i-1 C. n-i D. n-i+1 8. 在带头结点的双向循环链表中的 p 结点之后插入一个新结点 s, 其修改链的 java 语句序 列......

    在带头结点的双向循环链表中的 p 结点之后插入一个新结点 s,其修改链的 java 语句序列是( D )。 A. p.setNext(s); s.setPrior(p); p.getNext().set......

    在带头结点的双向循环链表中的 p 结点之后插入一个新结点 s,其修改链的 java 语句序列是( D )。 A. p.setNext(s); s.setPrior(p); p.getNext().set......

    19.对于一个头指针为 head 的带头结点的单链表,判定该表为空表的条件是( ...

    n-i D. n-i+1 8.在带头结点的双向循环链表中的 p 结点之后插入一个新 结点 s,其修改链的 java 语句序列是( D )。 A. p.setNext(s); s.setPrior......

    在带头结点的双向循环链表中的 p 结点之后插入一个新结点 s,其修改链的 java 语句序列是( D )。 A. (s); (p); ().setPrior(s); ()); B. (s);......

    展开全文
  • 不带头结点单链表结构体声明typedef struct Node{int data;struct Node *next;}Node, *LinkList;(1)初始化void InitLinkList(LinkList *plist) //plist为二级指针,主函数传递第一个结点指针的地址{assert(plist!=...

    不带头结点的单链表结构体声明

    typedef struct Node

    {

    int data;

    struct Node *next;

    }Node, *LinkList;

    (1)初始化

    void InitLinkList(LinkList *plist) //plist为二级指针,主函数传递第一个结点指针的地址

    {

    assert(plist!=NULL);

    if(plist == NULL)

    return;

    *plist = NULL;

    }

    (2)求链表长度

    int ListLength(LinkList plist) //不需要修改链表,则只需传递一级指针

    {

    int count=0;

    while(plist != NULL)

    {

    count++;

    plist=plist->next;

    }

    return count;

    }

    (3)得到某个结点,函数返回该结点

    LinkList GetNode(LinkList plist, int pos)

    {

    assert(plist!=NULL);

    if(plist == NULL)

    return NULL;

    LinkList p=plist;

    while(pos > 1) //pos为1即找到该位置,链表是从第一个结点算起

    {

    p=p->next;

    pos--;

    }

    return p;

    }

    (4)静态函数:申请结点空间

    static LinkList NodeApply(LinkList next, int val)

    {

    LinkList q=(Node *)malloc(sizeof(Node));

    assert(q != NULL);

    if (q == NULL)

    return NULL;

    q->data=val;

    q->next=next;

    return q;

    }

    (5)插入

    void Insert(LinkList *plist, int pos, int val)

    {

    assert(plist!=NULL);

    if(plist == NULL)

    return;

    if(pos < 0 || pos >ListLength(*plist))

    return;

    if(pos == 0) //头插要单独考虑

    {

    *plist=NodeApply(*plist,val); //即*plist指向新节点

    return;

    }

    LinkList p=GetNode(*plist, pos); //要插入其后的结点的位置

    p->next=NodeApply(p->next, val);

    }

    (6)头插

    void InsertHead(LinkList *plist, int val)

    {

    assert(plist!=NULL);

    if(plist == NULL)

    return;

    *plist=NodeApply(*plist,val);

    }

    (7)尾插

    void InsertTail(LinkList *plist, int val)

    {

    assert(plist!=NULL);

    if(plist == NULL)

    return;

    Insert(plist, ListLength(*plist), val);

    }

    (8)输出

    void Show(LinkList plist)

    {

    for(Node *p=plist; p!=NULL; p=p->next)

    {

    printf("%d -->",p->data);

    }

    printf("NULL\n");

    }

    (9)删除

    void Delete(LinkList *plist, int pos)

    {

    assert(plist != NULL);

    if(plist == NULL)

    {

    return;

    }

    if(pos<=0 || pos>ListLength(*plist))

    {

    return;

    }

    if(pos == 1) //头删特殊考虑

    {

    LinkList p=*plist;

    *plist=p->next;

    free(p);

    return;

    }

    LinkList p=GetNode(*plist, pos-1); //要删除结点的前一个结点

    LinkList q=p->next; //要删除的结点

    p->next=q->next;

    free(q);

    }

    (10)头删

    void DeleteHead(LinkList *plist)

    {

    assert(plist != NULL);

    if(plist == NULL)

    {

    return;

    }

    LinkList p=*plist;

    *plist=p->next;

    free(p);

    }

    (11)尾删

    void DeleteTail(LinkList *plist)

    {

    assert(plist != NULL);

    if(plist == NULL)

    {

    return;

    }

    Delete(plist,ListLength(*plist));

    }

    (12)判空

    int ListEmpty(LinkList plist)

    {

    if(plist == NULL) //第一个结点指针指向空

    return -1; //为空

    return 0;

    }

    (13)链表清空

    void ClearList(LinkList *plist)

    {

    assert(plist != NULL);

    if(plist == NULL)

    {

    return;

    }

    while(!ListEmpty(*plist)) //只要不为空

    {

    DeleteHead(plist);//头删

    }

    }

    主函数

    int main()

    {

    LinkList plist; //栈区定义一个结点指针类型

    InitLinkList(&plist);

    Insert(&plist,0,10);

    Insert(&plist,0,20);

    Insert(&plist,0,30);

    Insert(&plist,1,40);

    InsertHead(&plist,50);

    InsertTail(&plist,60);

    Show(plist);

    DeleteTail(&plist);

    Show(plist);

    ClearList(&plist);

    Show(plist);

    }

    展开全文
  • 带头结点和不带头结点单链表注意的小细节 在写不带头结点的单链表中发现了一个问题,这个问题在带头结点的单链表中也存在,那就是值传递的问题。 首先来看一下 #include&amp;amp;amp;lt;stdio.h&amp;amp;...

    带头结点和不带头结点单链表注意的小细节

    在写不带头结点的单链表中发现了一个问题,这个问题在带头结点的单链表中也存在,那就是值传递的问题
    首先来看一下

    #include<stdio.h>
    #include<malloc.h>
    #include<stdlib.h>
    #define Destroy Clear	//Destroy和Clear操作是一样的
    
    //和设头结点的单链表在定义存储结构上是相同的
    typedef struct Node
    {
    	int data;	//数据域
    	struct Node *next;	//指针域
    }NODE,*PNODE;
    
    PNODE Create2()
    {
    	//在表尾插入数据
    	int i,n;
    	PNODE pHead=NULL,pNew,pTail;
    	printf("请输入数据元素的个数:");
    	scanf("%d",&n);
    	if(n<1)
    		exit(-1);
    	pHead=(PNODE)malloc(sizeof(NODE));//生成一个首结点
    	if(NULL==pHead)
    		exit(-1);
    	printf("请输入第1个元素的值:");
    	scanf("%d",&pHead->data);
    	pHead->next=NULL;
    	pTail=pHead;
    	for(i=0;i<n-1;i++)
    	{
    		pNew=(PNODE)malloc(sizeof(NODE));
    		if(NULL==pNew)
    			exit(-1);
    		printf("请输入第%d个元素的值:",i+2);
    		scanf("%d",&pNew->data);
    		pNew->next=pTail->next;
    		pTail->next=pNew;
    		pTail=pNew;
    	}
    	return pHead;
    }
    void Clear(PNODE pHead)
    {
    	PNODE p=pHead;
    	while(p!=NULL)
    	{
    		p=pHead->next;
    		free(pHead);
    		pHead=p;
    	}
    }
    void Traverse(PNODE pHead)
    {
    	PNODE p=pHead;
    	while(p!=NULL)
    	{
    		printf("%d ",p->data);
    		p=p->next;
    	}
    	printf("\n");
    }
    
    int main()
    {
    	PNODE pHead=Create2();
    	printf("初始化后元素:");
    	Traverse(pHead);
    	printf("销毁链表后:\n");
    	Clear(pHead);
    	Traverse(pHead);
    	return 0;
    }
    

    这是从不带头结点的单链表源码中提取的一段代码,以下是程序运行结果

    为什么在程序最后会出现-572662307这样的乱码呢?而为什么在前一篇数据结构之带头结点的单链表中最后在销毁链表之后,并且遍历链表元素之后没有出现乱码呢?
    首先来看一下从上一篇提取问题代码之后的代码

    #include<stdio.h>
    #include<malloc.h>
    #include<stdlib.h>
    
    typedef struct Node
    {
    	int data;
    	struct Node *next;
    }NODE,*PNODE;
    
    PNODE Create2()
    {
    	int i,n;
    	PNODE pHead,pTail,pNew;
    	pHead=(PNODE)malloc(sizeof(NODE));
    	if(NULL==pHead)
    		exit(-1);
    	pHead->next=NULL;	//生成头结点
    	pTail=pHead;
    	printf("请输入数据元素的个数:");
    	scanf("%d",&n);
    	for(i=0;i<n;i++)
    	{
    		pNew=(PNODE)malloc(sizeof(NODE));
    		if(NULL==pNew)
    			exit(-1);
    		printf("请输入第%d个元素的值:",i+1);
    		scanf("%d",&pNew->data);
    		pTail->next=pNew;
    		pTail=pTail->next;
    		pNew->next=NULL;
    	}
    	return pHead;
    }
    void Destroy(PNODE pHead)
    {	//销毁pHead指向的单链表:头结点也不存在只剩一个头指针,且头指针为NULL
    	PNODE p;
    	while(pHead!=NULL)
    	{
    		p=pHead->next;
    		free(pHead);
    		pHead=p;
    	}
    }
    void Traverse(PNODE pHead)
    {
    	PNODE p=pHead->next;
    	while(p!=NULL)
    	{
    		printf("%d	",p->data);
    		p=p->next;
    	}
    	printf("\n");
    }
    int main()
    {
    	PNODE pHead=Create2();
    	printf("初始化后的元素:");
    	Traverse(pHead);
    	Destroy(pHead);
    	printf("销毁单链表后:");
    	Traverse(pHead);
    	return 0;
    }
    

    代码运行之后:
    在这里插入图片描述
    通过观察比较,表面的问题出现在Traverse()这个函数上,
    而两个Traverse的区别是:在带头结点的单链表中先执行

    p=pHead->next;
    

    然后判断p是否为空在输出p->data;
    而在不带头结点的单链表中先执行

    p=pHead;
    

    然后判断p是否为空在输出p->data;
    两者差别就在于不带头结点的输出的是pHead->data;带头结点输出的是pHead->next->data;
    下面来分析一下这个问题产生的原因:
    在这里插入图片描述注意:上图为执行不带头结点的Clear函数或Destroy函数,带头结点的Destroy函数执行图只不过就在第一个节点前添加一个头节点,但导致的问题都是相同的。
    首先,在Clear函数时,传递的实参是pHead,形参也是pHead,这样就相当于值传递,让实参和形参都指向相同的元素,但是销毁链表时,是形参的pHead在执行,当释放第一个节点后,形参pHead指向下一个元素,但实参由于指向第一个结点,并且已被释放,所以此时实参pHead内容为乱码,不再是0x01,但是在遍历的时候,不带头结点的会先判断pHead是否为空,因为其中为乱码所以不为空,所以会输出pHead->data为乱码,pHead指向它的下一个结点,检测到下一个结点为空,跳出while循环,所以执行结果会看到乱码,而在带头结点的在进行循环前pHead已经指向它的下一个结点,也就是说它的下一个结点已经为空,所以不会执行while循环,直接结束,也就不会看到乱码现象。

    这种问题该如何修改呢?
    以下提供了两种解决方法(以不带头结点的单链表为例)
    第一种:用C语言方式
    具体代码如下:

    void Clear(PNODE *pHead)
    {
    	PNODE p=*pHead;
    	while(p!=NULL)
    	{
    		p=(*pHead)->next;
    		free(*pHead);
    		*pHead=p;
    	}
    }
    int main()
    {
    	PNODE pHead=Create2();
    	printf("初始化后元素:");
    	Traverse(pHead);
    	printf("销毁链表后:\n");
    	Clear(&pHead);
    	Traverse(pHead);
    	return 0;
    }
    

    对以上两个函数进行修改即可
    下面给出修改后的函数执行图:
    在这里插入图片描述
    当释放第一个节点后
    在这里插入图片描述注意:形参pHead存储的是实参pHead变量本身的地址,而通过在函数里使用*pHead意义就是代表形参pHead的内容,也就是实参pHead,由此可以看出修改前后的区别就是,修改前是通过形参来操作函数的销毁,实参不动。而修改过后通过形参控制实参,由实参来操作函数的销毁。由此可以看出两者的本质区别
    第二种:用c++引用实现

    void Clear(PNODE &pHead)
    {
    	PNODE p=pHead;
    	while(p!=NULL)
    	{
    		p=pHead->next;
    		free(pHead);
    		pHead=p;
    	}
    }
    int main()
    {
    	PNODE pHead=Create2();
    	printf("初始化后元素:");
    	Traverse(pHead);
    	printf("销毁链表后:\n");
    	Clear(pHead);
    	Traverse(pHead);
    	return 0;
    }
    

    在原始错误的基础上只需要将Clear函数的形参改为(PNODE &pHead)即可。
    另外一个值得注意的是在对不带头结点的单链表进行插入和删除操作时传递参数必须是以上的两种方式(如果不采用传递参数方式,也可以采用返回头指针的方式,如创建链表),这也是和带头结点单链表在插入和删除操作上的重要区别

    展开全文
  • c代码-不带头结点单链表创建——头插法
  • 关键字:2个带头结点单链表+判断子序列 思路 关注:递归算法的设计重点在于找到“递归”的部分,即重复调用函数,改变部分相关变量 设f(L,x)的功能是:删除以L为首结点指针的单链表中所有值等于x的结点,显然有f(L-&...

    题目:两个整数序列A=a1,a2,a3…am和b1,b2,b3。。。bn已经存入两个单链表中,设计一个算法,判断序列B是否为序列A的连续子序列。
    关键字:2个不带头结点单链表+判断子序列

    思路
    B是A的子序列的充分条件:B的所有元素都存在于A中,且排列顺序也相同。
    意味着:A中某个元素就是B的开头元素,这里叫她子序列首元素“”
    我们需要对每一个A元素进行向后扫描,检查其是否是子序列首元素,考察其是否承担得起以下功能:1.本身值等于B首元素,2.之后所有元素的值和B首元素之后所有元素的值相同

    1.确定子序列首元素 ,同时遍历AB,
    a.当下A元素不等于B首元素。这个元素一定不是子序列首元素
    A向后扫描寻找新机会,B牢牢卡主首元素的位置,直到A找到相同元素,然后再AB同时向后扫描验证B是否为子序列

    b.当下A元素等于B首元素。这个元素可能是子序列首元素,利用pre指针在A中保存这个“疑似子序列首元素”

    (因为万一之后发现功能2不满足,需要从这个元素的下一个元素开始再次判定是否为“子序列首元素”
    eg:A:1,2,5,5,5,10,4
    B:5,5,10
    可以看到,虽然第一个5不是“子序列首元素”,但第二个5是的,而当你判断到第一个5不是“子序列首元素”时,pa指针已经在第三个5上了,所以我们需要pre来保存“**疑似子序列首元素”**的位置。
    之后,需要从pre->next开始,“”判定其是否为“子序列首元素”

    两表同时后移指针;

    a)、若对应数据相等,则两表同时后移指针;
    b)、若对应数据不等,则“疑似子序列首元素”确定不是“子序列首元素。”
    A链表从上次开始比较结点的后继,即“疑似子序列首元素的下一个元素”开始,重复上述判断其是否为“子序列首元素的过程。

    需要变量:La,Lb,各自工作指针 pa , pb, 记忆开始结点小助手 pre

    int Pattern(LinkList La,LinkList Lb){
        LNode*pa=La;
        LNode*pb=Lb;
        LNode*pre=pa;//pre是记住每趟比较中A链表的开始结点,即每一次的“疑似子序列首元素”
        while(pa&&pb)
          if(pa->data==pb->data){
            pa=pa->next;
            pb=pb->next;
            }
          else {
            pre=pre->next;//开始下一个“疑似子序列首元素”的验证过程
            pa=pre;//pa工作指针,从新位置开始遍历
            pb=Lb;//pb需要从首指针开始
            }
        if(pb==NULL)//遍历A的过程没结束之前,B已经结束了,说明A包含了B
           return 1;
       else//A遍历完了的情况下,B还在首位,说明A没有包含B
          return 0;
    }
    
    展开全文
  • 不带头结点单链表

    2018-10-11 16:10:37
    Link.h typedef int ELEM_TYPE; typedef struct Node { ELEM_TYPE data; struct Node* next; }Node,*PNode; void Init(PNode* phead); PNode BuyNode(ELEM_TYPE val...bool InsertTail(PNode* phead,ELEM_TYPE...
  • 带头结点单链表 public class Entry<T extends Comparable<T>> {//自定义数据类型才需要重写compareTo方法 private T value; private Entry<T> next; public Entry(){//头结点 } ...
  • 利用c++实现不带头结点链表的基本操作实现,如逆序建立链表,插入、删除链表元素等。
  • 目录不带头结点单链表的操作1.结构体定义2.初始化单链表3.判断元素位置的合法性4.在第i位置之前的插入元素e5.删除第i元素,并由e返回其值 不带头结点单链表的操作 不带头结点单链表操作中,除了InitList()...
  • 带头结点单链表实现 [code="java"]public class LinkedList { private Entry head, tail; //头指针,尾指针 private int size; //通过一个变量记录链表长度 public LinkedList() { //生成...
  • 不带头结点单链表的基本操作

    千次阅读 2020-03-05 14:54:28
    定义结点 typedef struct LNode{ int data; //每个节点存放一个数据元素 struct LNode *next; //指针指向下一个节点 }LNode,*LinkList;...//初始化一个空的单链表 bool InitList(LinkList &L){ L = NU...
  • 实现单链表及其一些基本操作函数(不带头结点) 1.头文件包含 2.宏定义及节点类型描述 3.初始化、判断是否为空 4.指定位置插入操作 5.在p节点后插入元素e 6.在p节点前插入元素e 7.删除操作:删除第i节点,...
  • 设计一个递归算法,删除不带头结点单链表L中所有值为X的结点。 根据题目中,删除单链表L中所有值为X的结点,也就把if(data == x)的值删掉。本题的重点是考察递归算法,同时要求单链表不带头结点。 那么,下面...
  • 2,带头结点单链表的定义及源代码
  • 对于不带头结点单链表 L,设计一个递归算法逆序输出所有结点值 #include "LinkList.cpp" #include <bits/stdc++.h> void Revdisp(LinkNode *L) { // 逆序输出 if(L == NULL) return ; else{...
  • 不带头结点单链表结构体声明 typedef struct Node { int data; struct Node *next; }Node, *LinkList; (1)初始化 void InitLinkList(LinkList *plist) //plist为二级指针,主函数传递第一个结点指针的地址 { ...
  • 1、带头结点单链表就地逆置算法 部分函数调用参考如下:https://blog.csdn.net/qq_50504109/article/details/120288749 /** * 单向链表的逆置,说白了就是头插法的利用,只不过我们这次插入的数据,不是自己决定的...
  • 文章目录一、带头结点与不带头结点单链表的区别二、不带头结点单链表的实现 一、带头结点与不带头结点单链表的区别 带头结点的单链表,带头结点的单链表在初始化时产生一个 head 结点,其 data 域和 next 域均为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,710
精华内容 5,084
关键字:

对于一个不带头节点的单链表