(数据结构)链表

链表

单链表

单链表是由若干结点构成

单链表的结点只有一个指针域(单链表包含一个指针域和一个数据域)

链表的结构

头指针:指向第一个结点的地址

尾标志:终端结点的指针域为空

 

申请一个结点
typedef struct node
{
	DataType data;     //数据域
	struct node *next;   //指针域
}Node,*Link;   
//用typedef去声明结构体时,Node和*Link两个位置就被定义成了类型
Node st;    //struct node st;
Link p;     //struct node *p;  //p是一个指向结构体的指针
申请结点
p=(Link)malloc(sizeof(Node));
sizeof(node);     //计算出node结点的大小
malloc(sizeof(Node));   //用malloc分配给Link这么大的空间  malloc返回函数时viod*

分配地址以后,其把首地址分配给了指针p,在使用这块空间的时候,需要对这块地址进行强制转换。转换成指针p希望看到的类型。

指针p是一个Link类型,所以把malloc也定义成Link类型

 

如何引用数据元素?

(*p).data;
p->data;

如何引用指针域?

p->next;

 

链表的实现

单链表的遍历操作

操作接口:void displayNode(Link head);

void displayNode(Link head)
{
	p= head->next;
	while(p!=NULL)
	{
	cout<<p->next<<endl;
	p = p->next;
	}
}

求单链表的元素个数

操作接口:int length(Link head);

int length(Link head){
	p = head->next;    //p指向头指针的next域
	count = 0;         //count的数值为零
	while(p!=NULL)
	{
		p = p->next;    //如果p不为空,则p指向下一个结点的                           // next域
		count++;
 	}
 	return count;      //注意count和初始化返回值之间的关系
}

 

单链表的查找操作

int queryNode(Link head,DaraType x){
	p = head->next;
    count = 0;
    while(p!=NULL)
    {
        if(p—>data==x)
        {
            cout<<data<<endl;    //找到则调用输出函数,并提                                  //前返回true
            return true;
        }
        p = p->next;
	}
    //如果链表结束,说明没有找到
    return false;
}

单链表的插入操作

操作接口:void insertNode(Link head,int i,DataType x);

node = (Link)malloc(sizeof(Node)); //申请一个结点node
node->data = x;                    //结点的数据域是x
node -> next = p->next;            //p的next域赋给node的                                    //next域
p->next = node;          //将node的数据域赋值给p的next域

  1. 工作指针p初始化

  2. 查找第i-1个结点并使用、工作指针p指向该结点

  3. 若查找不成功,则返回false

    3.1生成一个元素值为x的新结点;

    3.2将新结点s插入到结点p之后;

    3.3返回true;

     

bool insertNode(Link head,int i,DataType x)
{
    p = head;          //工作指针p指向头结点
    count = 0;
    while (p!=NULL&&count<i-1) //查找第i-1个结点
    {
        p=p->next;
        count++;
    }
    if(p==NULL)
    	return false;  //没有找到第i-1个结点
    else{
        node = (Link)malloc(sizeof(Node));//申请一个结点                                             //node
        node->data=x;
        node->next=p->next; //结点node插入结点p之后
        p->next=node;
        return ture;
    }
}

 

创建一个单链表—头插法

操作接口:Link newList(DataType a[],int n)

头插法:将待插入结点插在头结点的后面。

初始化头结点
head = (Link)malloc(sizeof(Node));
head->next=NULL;
image-20221005111133614.png
插入第一个元素
node = (Link)malloc(sizeof(Node));
node->data=a[0];
node->next=head->next;
head->next=node;

node = (Link)malloc(sizeof(Node));
node->data=a[1];
node->next=head->next;
head->next=node;

template <class DataType>
Link newList(DataType a[],int n)
{
    head=(Link)malloc(sizeof(Node));
    head->next=NULL;
    //创建后续结点
    for(i = 0; i < n;i++)
    {
        node = (Link)malloc(sizeof(Node));
        node->data = a[i];
        node->next = head->next;
		head->next = node;    
    }
    return head;
}

 

创建一个单链表—尾插法

操作接口:Link newList(DataType a[],int n)

尾插法:将待插入结点插在终端结点的后面

head = (Link)malloc(sizeof(Node));  //创建一个头
head->next = NULL;           
rear = head;               //将head赋给rear

插入第一个元素结点
node = (Link)malloc(sizeof(Node)); //创建结点node
node->data = a[0];         //结点第一个数据域
rear->next = node;         //rear的next域是node
rear = node;               //将node名为rear

依次插入每一个结点
node = (Link)malloc(sizeof(Node))
node->dat = a[1];
rear->next = node;
rear = node;

尾插法
Link newList(DataType a[],int n)
{
  	head = (Link)malloc(sizeof(Node));
  	head->next = NULL;
  	rear = head;         //尾指针初始化
  	for(i = 0; i<n;i++)
  	{
  	 	node=(Link)malloc(sizeof(Node));//创建结点
  	 	node->data = a[i];
  	 	rear->next = node;
  	 	rear = ndoe;
  	}
  	rear->next = NULL;
  	return head;
}

 

单链表结点的删除

操作接口:bool deleteNode(Link head, Datatype x);

q->next = p->next;
free(p);     

将q的next域指向p的next域,将被删除的p空间释放。

查找结点

在查找过程中,如果发现p所指向的结点data值不是要找的x,则p,q同时后移;一旦找到则执行删除操作

 

查找到p结点并将其删除

1.如何找到p结点。

2.如何保证p,q指针一前一后。

 

初始化
p = head->next;
q = head;
指针移动一次
q = p;
p = p->next;
删除中的特殊情况

在查找过程中,如果一直没有找到data域为x的结点,或者发现待删除的表是空表,则提前返回false

if(head==NULL||head->next==NULL){
	return false;
}
单链表的删除

1.判断是否是空表,如果是空表返回false;

2.工作指针p,q初始化

3.若p指针不为空,则继续下列循环:

​ 3.1如果找到data域等于x的结点,则:

​ 3.1.1摘链,将结点p的从链表上摘下来

​ 3.1.2释放别删除的结点

​ 3.1.3提前返回true,代表删除成功

4.循环结束了,说明没有找到和x相等的结点,则返回false

 

bool deleteNode(Link head,DataType x){
	if(head==NULL||head->next==NULL){
	return false;
	}
	p=head->next;
	q=head;
	while(p!=NULL){
		if(p->data==x){
		q->next=p->next;
		free(p);    //单链表的释放
		return true;
		}
		else{
			q = p;
			p = p->next;
		}
	}
	//如果循环结束了,说明没有找到和x相关的结点
	return false;
}

 

循环列表的实现

将单链表的首位相接,将终端结点的指针由空指针改为指向头结点,构成单循环链表,简称循环链表

 

循环链表的插入
node = (Link)malloc(sizeof(Node));
node->data = x;
node->next = p->next;
p->next = node;

 

p! = NULL;     //p != head
p->next != NULL;    //p->next != head 

 

双向链表

在单链表的每一个结点中再设置一个指向其前驱结点的指针域。

data:数据域,储存数据元素

prior:指针域,储存该结点的前驱结点地址

next:指针域,储存该结点的后继结点地址

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y江江江江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值