输入一组整数,建立带头结点的单链表,并实现线性表的求长度、插入和删除等操作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了输入一组整数,建立带头结点的单链表,并实现线性表的求长度、插入和删除等操作?相关的知识,希望对你有一定的参考价值。

自己写的,不过是用的c++,希望能帮到你。
#include <iostream>
using namespace std;

struct Node

int Value;
Node *next;
;

//创建链表
Node *CrtNode(int n)

Node *head; //声明头指针head
Node *p,*s;
int x;
head=new Node; //创建头结点由head指向(空的头结点)
s=head;
cout<<"请输入数字:"<<endl;
for(int i=0;i<n;i++)

p=new Node; //创建一个结点
cin>>x;
p->Value=x; //把输入的x的值赋给创建的结点
s->next=p; //把创建的结点由s的next指向
s=p; //指针s的指向向后移一个结点

p->next=NULL; //最后一个结点的next指向空
return head; //返回头指针


//显示
void ShowNode(Node *head)

Node *p;
//显示除头结点以后所有结点(因为创建时头结点为空)
p=head->next;
while(p!=NULL)

cout<<p->Value<<" ";
p=p->next;

cout<<endl;


//排序(从大到小)
void paixu(Node *head,int n)

Node *p,*s;
//对所有值排序(冒泡排序)
for(int i=0;i<n-1;i++)

p=head->next;
for(int j=0;j<n-i-1;j++)

s=p->next;
if(p->Value<s->Value)

int N=p->Value;
p->Value=s->Value;
s->Value=N;

p=p->next;




//插入
void InsNode(Node *head)

int newValue;
Node *p,*s,*d;

s = head; //s为头结点
d = s->next; //d为s的后一个结点
cout<<"请输入需要插入的数:";
cin>>newValue;
p=new Node; //创建需要插入的结点
p->Value = newValue;
p->next = NULL;
if(d == NULL) //如果链表为空,直接插在头结点后面
s->next = p;
else
//不为空链表则循环
while(1)

if(p->Value >= d->Value) //如果待插入结点的值不小于d结点则插到d结点前,跳出循环

s->next = p;
p->next = d;
break;

else if(d -> next == NULL) //如果待插入的结点的值小于最后一个结点,则插在最后结点之后,跳出循环

d->next = p;
break;

s = d; //
d = d->next; //指针s,d的指向都向后跳一个结点




//删除
void DelNode(Node *head)

Node *p,*s;
int delValue;
p = head;
s = p->next;
cout<<"请输入需要删除的数:";
cin>>delValue;
if(s == NULL) //判断空链表
cout<<"这是一个空链表!"<<endl;
else

while(s != NULL&&s->Value != delValue) //判断s结点的值是否等于输入的值,不等于则指针p,s指向向后移一个结点

p = s;
s = s->next;


if(s != NULL) //已经找到,则删除S结点

p->next = s->next;
delete s;

else //没有找到
cout<<"没有找到要删除的数值!"<<endl;




//计算长度
int LenNode(Node *head)

Node *p;
//头结点没有计入
p=head->next;
int count=0;
while(p)

p=p->next;
count++;

return count;


void contraryNode(Node *head)

Node *p,*s,*t = NULL; //声明一个辅助结点
p = head->next; //p指向头结点后的第一个结点
while(p != NULL) //p结点不为空

s = p;
p = p->next;
s->next = t;
t = s;

head->next = t;


int main()

Node *head;
int n;
char ch;
cout<<"请输入需要创建的链表的结点数:";
cin>>n;
head=CrtNode(n);
paixu(head,n);
cout<<"此链表共有 "<<LenNode(head)<<" 个结点."<<endl;
cout<<"排序后:";
ShowNode(head);
contraryNode(head);
cout<<"逆置后:";
ShowNode(head);
paixu(head,n);
cout<<"排序后:";
ShowNode(head);
do

InsNode(head);
ShowNode(head);
DelNode(head);
ShowNode(head);
cout<<"此链表共有 "<<LenNode(head)<<" 个结点."<<endl;
cout<<"是否继续操作(Y/N)?";
cin>>ch;

while(ch=='y'||ch=='Y');
return 0;
参考技术A de "stdafx.h"
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
struct LNode

ElemType data;
struct LNode *next;
;

//***********************************************************置空表setnull()
void setnull(struct LNode **p)

*p=NULL;


//************************************************************求长度length()
int length(struct LNode **p)

int n=0;
struct LNode *q=*p;
while (q!=NULL)

n++;
q=q->next;

return(n);


//*************************************************************取结点get()
ElemType get(struct LNode **p,int i)

int j=1;
struct LNode *q=*p;
while (j<i && q!=NULL) /**//*查找第i个结点*/

q=q->next;j++;

if (q!=NULL) /**//*找到了第i个结点*/
return(q->data);
else

printf("位置参数不正确!\n");
return NULL;



//************************************************************按值查找locate()
int locate(struct LNode **p,ElemType x)

int n=0;
struct LNode *q=*p;
while (q!=NULL && q->data!=x) /**//*查找data域为x的第一个结点*/

q=q->next;
n++;

if (q==NULL) /**//*未找到data域等于x的结点*/
return(-1);
else /**//*找到data域等于x的结点*/
return(n+1);


//**********************************************************插入结点insert()
void insert(struct LNode **p,ElemType x,int i)

int j=1;
struct LNode *s,*q;
s=(struct LNode *)malloc(sizeof(struct LNode)); /**//*建立要插入的结点s*/
s->data=x;
q=*p;
if (i==1) /**//*插入的结点作为头结点*/

s->next=q;
*p=s;

else

while (j<i-1 && q->next!=NULL) /**//*查找第i-1个结点*/

q=q->next;j++;

if (j==i-1) /**//*找到了第i-1个结点,由q指向它*/

s->next=q->next; /**//*将结点s插入到q结点之后*/
q->next=s;

else
printf("位置参数不正确!\n");



//*********************************************************删除结点del()
void del(struct LNode **p,int i)

int j=1;
struct LNode *q=*p,*t;
if (i==1) /**//*删除链表的头结点*/

t=q;
*p=q->next;

else

while (j<i-1 && q->next!=NULL) /**//*查找第i-1个结点*/

q=q->next;j++;


if (q->next!=NULL && j==i-1) /**//*找到第i-1个结点,由q指向它*/

t=q->next; /**//*t指向要删除的结点*/
q->next=t->next; /**//*将q之后的结点删除*/

else printf("位置参数不正确!\n");

if (t!=NULL) /**//*在t不为空时释放该结点*/
free(t);


//********************************************************显示链表display()
void display(struct LNode **p)

struct LNode *q;
q=*p;
printf("单链表显示:");
if (q==NULL) /**//*链表为空时*/
printf("链表为空!");
else if (q->next==NULL) /**//*链表只有一个结点时*/
printf("%c\n",q->data);
else /**//*链表存在一个以上的结点时*/
while (q->next!=NULL) /**//*显示前面的结点*/

printf("%c→",q->data);q=q->next;


printf("%c",q->data); /**//*显示最后一个结点*/


printf("\n");


void main()

struct LNode *head;
setnull(&head);
insert(&head,'a',1);
insert(&head,'b',2);
insert(&head,'a',2);
insert(&head,'c',4);
insert(&head,'d',3);
insert(&head,'e',1);
display(&head);
printf("单链表长度=%d\n",length(&head));
printf("位置:%d 值:%c\n",3,get(&head,3));
printf("值:%c 位置:%d\n",'a',locate(&head,'a'));
printf("删除第1个结点:");
del(&head,1);
display(&head);
printf("删除第5个结点:");
del(&head,5);
display(&head);
printf("删除开头3个结点:");
del(&head,3);
del(&head,2);
del(&head,1);
display(&head);


/**//*
运行结果:
单链表显示:e→a→a→d→b→c
单链表长度=6
位置:3 值:a
值:a 位置:2
删除第1个结点:单链表显示:a→a→d→b→c
删除第5个结点:单链表显示:a→a→d→b
删除开头3个结点:单链表显示:b
*/
参考技术B 求长度只能循环,设置一个指针p,
if ( p -> next ! = NULL)
p = head->next , p = p->next , i++ ' i ' 是用来计算总长度的
如果是插入操作 则在定义一个指针 f,以在头结点插入数据为例
f -> next = head -> next , head -> next = f
如果是删除操作,定义一个指针 m ,以删除头结点后一节点为例
head -> next = m -> next , free ( m )
希望对你有帮助

循环链表的建立及各种操作

循环链表

  循环链表是一个收尾相接的链表,将单链表的最后一个指针域改由NULL改为指向表头结点这就是单链式的循环链表,并称为循环单链表

  技术分享图片

  带头结点的循环单链表的各种操作的算法实现与带头结点单链表的算法实现类似,差别仅在于算法判别当前结点p是否为尾结点的条件不同。单链表中的判别条件为p!=NULL或p->next!=NULL,而单循环链表判别条件是p!=L或p->next!=L

  在循环单链表中附设尾指针有时候比附设头指针更简单。如:在用头指针的循环单链表中找a1的时间复杂度是O(1),找an需要从头找到尾,时间复杂度是O(n),如果用为指针rear,找开始结点和终端结点的存储位置分别是rear->next->next和rear

  建立循环单链表

void CreatCLLinkList(CLLinkList CL) 
{
    Node *rear,*s;
    rear=CL;//rear指针动态指向当前表尾,其初始值指向头结点 
    int flag=1;
    int x;
    printf("Please input data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            rear->next=s;
            rear=s;
        }
        else
        {
            flag=0;
            rear->next=CL;//最后一个节点的next域指向头结点 
        }
    }
}

  循环单链表的插入

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *next;    
}Node,*CLLinkList;

void InitCLLinkList(CLLinkList *CL)
{
    *CL=(CLLinkList)malloc(len);
    (*CL)->next=*CL;
}

void CreatCLLinkList(CLLinkList CL) 
{
    Node *rear,*s;
    rear=CL;//rear指针动态指向当前表尾,其初始值指向头结点 
    int flag=1;
    int x;
    printf("Please input data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            rear->next=s;
            rear=s;
        }
        else
        {
            flag=0;
            rear->next=CL;//最后一个节点的next域指向头结点 
        }
    }
}

void PrintCLLinkList(CLLinkList CL)
{
    Node *p;
    p=CL->next;
    printf("You input data is:
");
    for(;p!=CL;p=p->next)
    {
        printf("%-3d",p->data);
    }
    printf("
");
}

void InCLLinkList(CLLinkList CL,int i,int x)
{
    Node *p,*s;
    int k=0;
    p=CL;
    if(i<=0)
    {
        printf("You enter location illegal:
");
        return;
    }
    while(p->next!=CL&&k<i-1)
    {
        k++;
        p=p->next;
    }
    if(p==CL)
    {
        printf("The insert position is not reasonable:
");
        return;
    }
    s=(Node *)malloc(len);
    s->data=x;
    s->next=p->next;
    p->next=s;
    printf("Insert successfully
");
}

void Print_CLLinkList(CLLinkList CL)
{
    Node *p;
    p=CL->next;
    printf("Now you input data is:
");
    for(;p!=CL;p=p->next)
        printf("%-3d",p->data);
}

int main()
{
    int i,x;
    CLLinkList CL;
    InitCLLinkList(&CL);
    CreatCLLinkList(CL);
    PrintCLLinkList(CL);
    
    printf("Please enter the location you want to insert:
");
    scanf("%d",&i);
    printf("Please enter the values you want to insert:
") ;
    scanf("%d",&x);

    InCLLinkList(CL,i,x);
    Print_CLLinkList(CL);
    free(CL);
    return 0;
}

  循环单链表的删除

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)
typedef struct Node
{
    int data;
    struct Node *next;
}Node,*LinkList;

void InitCLLinkList(LinkList *CL)
{
    *CL=(LinkList)malloc(len);
    (*CL)->next=*CL;
}
void CreatCLLinkList(LinkList CL)
{
    int flag=1,x;
    Node *rear,*s;
    rear=CL;
    printf("Please input data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            rear->next=s;
            rear=s;
        }
        else
        {
            rear->next=CL;
            flag=0;
        }
    }
}

void DeleCLLinkList(LinkList CL,int i)
{
    Node *p,*r;
    p=CL;
    int k=0;
    if(i<0)
    {
        printf("You enput i illegal!
");
        return;
    }
    while(p->next!=CL&&k<i-1)
    {
        p=p->next;
        k++;
    }
    if(p->next==CL)
    {
        printf("Delete Node i illegal!
");
        return;
    }
    r=p->next;
    p->next=r->next;
    free(r);
}

void PrintCLLinkList(LinkList CL)
{
    Node *p;
    for(p=CL->next;p!=CL;p=p->next)    
    {
        printf("%3d",p->data);
    }
}
int main()
{
    LinkList CL;
    int i;
    InitCLLinkList(&CL);
    CreatCLLinkList(CL);
    
    printf("Please enter the i node you want to delete:
");
    scanf("%d",&i);
    DeleCLLinkList(CL,i);
    printf("The list after deleting is:
");
    PrintCLLinkList(CL);
    free(CL);
    
    return 0;
}

  合并循环单链表

    方法一:先找到两个链表LA,LB的表尾,分别用p,q指向它,然后将第一个链表的表尾与第二个链表的第一个结点连起来,修改第二个表的尾q,使它的链域指向第一个表头

//头指针合并循环链表 
#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *next;
}Node,*CLLinkList;

void InitCL_aLinkList(CLLinkList *CL_a)
{
    *CL_a=(CLLinkList)malloc(len);
    (*CL_a)->next=*CL_a;
}

void InitCL_bLinkList(CLLinkList *CL_b)
{
    *CL_b=(CLLinkList)malloc(len);
    (*CL_b)->next=*CL_b;
}

void CreatCL_aLinkList(CLLinkList CL_a)
{
    Node *p,*s;
    int x,flag=1;
    p=CL_a;
    printf("Please input A data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            p=s;
        }
        else
        {
            p->next=CL_a;
            flag=0;
        }
    }
}

void CreatCL_bLinkList(CLLinkList CL_b)
{
    Node *p,*s;
    int x,flag=1;
    p=CL_b;
    printf("Please input B data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            p=s;
        }
        else
        {
            p->next=CL_b;
            flag=0;
        }
    }
}

CLLinkList MergeCLLinkList(CLLinkList CL_a,CLLinkList CL_b)
{
    Node *p,*q;
    p=CL_a;
    q=CL_b;
    while(p->next!=CL_a)//找到LA的表尾,用p指向它 
        p=p->next;
    while(q->next!=CL_b)//找到LB的表尾,用q指向它
        q=q->next;
    q->next=CL_a;//修改LB的表尾指针,使之指向表LA的头结点 
    p->next=CL_b->next;    //修改LA的表尾指针,CL_b->next的意思是跳过CL_b头结点
    free(CL_b);
    return CL_a;
}

void PrintCLLinkList(CLLinkList CL)
{
    printf("CL list is:
");
    for(Node *p=CL->next;p!=CL;p=p->next)
        printf("%-3d",p->data);
    printf("
");
}

int main()
{
    CLLinkList CL_a,CL_b,CL;
    InitCL_aLinkList(&CL_a);
    InitCL_bLinkList(&CL_b);
    
    CreatCL_aLinkList(CL_a);
    CreatCL_aLinkList(CL_b);
    
    CL=MergeCLLinkList(CL_a,CL_b);
    PrintCLLinkList(CL_a);
    free(CL_a);
    return 0;
}

    方法二:若采用尾指针设置,无需遍历找到尾结点,只需修改尾指针的指示域即可

CLLinkList MergeCLLinkList(CLLinkList RA,CLLinkList RB)
{
    Node *p=RA->next;//保存RA的头结点地址 
    RA->next=RB->next->next;//RB的头结点练到RA的终端结点之后
    RB->next=p;//将RA的头结点链到RB的终端结点之后
    free(RB->next);//释放RB的头结点 
    return RB;//返回新的链表的尾指针 
}

  循环链表求长度

#include<stdio.h>
#define len sizeof(Node)
#include<stdlib.h>
typedef struct Node
{
    int data;
    struct Node* next;
}Node,*LinkList;

void InitCLLinkList(LinkList *CL)
{
    *CL=(LinkList)malloc(len);
    (*CL)->next=*CL;
}

//尾插法创建循环链表 
void CreatCLLinkList(LinkList CL)
{
    Node *s,*rear;
    int flag=1;
    rear=CL;
    printf("please input datas and input 0 over:
");
    int x;    
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
           s=(Node *)malloc(len);
        s->data=x;
        rear->next=s;
        rear=s;
        }
        else
        {
            flag=0;
            rear->next=CL;
        }
    }
}

int LengthCLLinkList(LinkList CL)
{
    int i=0;
    Node *p;
    p=CL->next;
    while(p!=CL)
    {
        i++;
        p=p->next;
    }
    return i;
}

int main()
{
    LinkList CL;
    int length;
    InitCLLinkList(&CL);
    CreatCLLinkList(CL);
    length=LengthCLLinkList(CL);
    printf("The length of the circular list is:%d
",length);
    free(CL) ;
    return 0;
}

 

以上是关于输入一组整数,建立带头结点的单链表,并实现线性表的求长度、插入和删除等操作?的主要内容,如果未能解决你的问题,请参考以下文章

算法习题---线性表之单链表的查找

循环链表的建立及各种操作

单链表练习题

数据结构之单链表

线性表文档之循环单链表

什么叫带头结点的链表? 什么叫不带头结点的链表?