C语言学习DAY4:数据结构,链表,头插法,尾插法,按位查找,按值查找
C语言学习DAY4:数据结构,链表,头插法,尾插法,按位查找,按值查找
(2)链表
单链表结点的定义:
typedef struct LNode//单链表结点类型,LNode不能省略,因为结构体内使用了LNode
{
ElemTpye data;//数据域
struct LNode *next;//指针域
}LNode,*LinkList;
头指针:链表第一个结点的存储位置,用来标识单链表。
头结点:在单链表第一个结点之前附加的一个结点,为了操作上的方便。
若链表有头结点,则头指针永远指向头结点,不论链表是否为空,头指针均不为空,头指针是链表的必须元素,他标识一个链表。
头结点是为了操作的方便而设立的,其数据域一般为空,或者存放链表的长度。但头结点不是必须的。
L为链表的头指针,则L->next为链表的第一个实质性元素,及L头指针指向头结点,然后L->可以理解为头结点的指针域,指向链表的第一个实质性元素。
链表优点:插入和删除不需要移动元素,只需要修改指针。
不需要大量的连续的存储空间。
链表缺点:单链表附加指针域,也存在浪费存储空间的缺点。
查找操作时需要从表头开始遍历,依次查找,不能随机存取。
//链表插入
//创建新结点
q=(LNode*)malloc(sizeof(LNode));
q->data=x;
//头部和中间插入方法
q->next=p->next;//p为插入的q前的数据
p->next=q;
//尾部插入方法
p->next=q;
q->next=NULL;
//链表删除
p=GetElem(L,i-1);
p->next=q->next;
free(q);
//链表按位置查找
LNode *p=L->next;//L为头指针,L->指向链表的第一个实质性元素
int j=1;
while(p&&j<i)//p为非末尾元素时为非空,i为查到的元素序号,直至j=i时p查找到
{
p=p->next;
j++
}
return p;
//链表按值查找
LNode *p=L->next;
while(p!=NULL&&p->data!=e)
{
p=p->next;
}
return p;
//头插法新建链表
开始->定义链表头指针->头结点申请空间->scanf读取第一个元素值->开启while循环建链表->打印链表->结束
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
//LNode*是结构体指针和LinkList是完全等价的
void list_head_insert(LNode* &L)
{
L=(LinkList)malloc(sizeof (LNode));//申请头结点空间,头指针指向头结点
L->next=NULL;
ElemType x;
scanf("%d",&x);//头结点不存放数据,所以x放在第一个数据元素里面
LNode* s;//用来申请新的结点
while(x!=9999)
{
s=(LinkList)malloc(sizeof (LNode));
s->data=x;
s->next=L->next;//s的next指向原本链表的第一个结点
L->next=s;
scanf("%d",&x);
}
}
void print_list(LinkList L)//L前没有&,所以函数内L的改变不会引起函数外L改变
{
L=L->next;
while(L!=NULL)
{
printf("%3d",L->data);
L=L->next;
}
printf("\n");
}
int main() {
LinkList L;//L是链表头指针你
list_head_insert(L);
print_list(L);
return 0;
}
//尾插法新建链表
开始->定义链表头指针->头结点申请空间,定义尾指针r,指向头结点L->scanf读取第一个元素值->开启while循环建链表->打印链表->结束
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode* next;
}LNode,*LinkList;
void list_tail_insert(LinkList &L)
{
L=(LinkList) malloc(sizeof (LNode));
L->next=NULL;
ElemType x;
LNode *s,*r=L;//s用来指向新结点,r始终指向链表尾
scanf("%d",&x);
while(x!=9999)
{
s=(LinkList) malloc(sizeof (LNode));
s->data=x;
r->next=s;//新结点给尾结点的next指针
r=s;//r要指向新的尾部
scanf("%d",&x);
}
r->next=NULL;//让尾结点的next为NULL
}
void print_list(LinkList L)
{
L=L->next;
while(L!=NULL)
{
printf("%3d",L->data);
L=L->next;
}
printf("\n");
}
int main()
{
LinkList L;
list_tail_insert(L);
print_list(L);
return 0;
}
//链表按位置查找及按值查找
//链表中L头结点是位置0,第一个元素值是位置1
LinkList GetElem(LinkList L,int SearchPos)//链表按位置查找
{
int i=0;
if (SearchPos<0)
return 0;
while(L&&i<SearchPos)
{
L=L->next;
i++;
}
return L;
}
int main()
{
LinkList L;
list_tail_insert(L);
LinkList search;//用来存储拿到的某个结点
search=GetElem(L,2);
printf("%d",search->data);
return 0;
}
//链表按值查找
LinkList LocatElem(LinkList L,ElemType SearchVal)//链表按值查找
{
while(L)
{
if(L->data==SearchVal)
return L;
else
L=L->next;
}
return NULL;
}
int main()
{
LinkList L;
list_tail_insert(L);
LinkList search;
search= LocatElem(L,2);
printf("%d",search->data);
return 0;
}
//往第i个位置插入元素
开始->定义链表头指针->尾插法新建链表->要插入第i个位置,我们通过GetElem按位置查找函数拿到第i-1个位置的元素地址->把新结点放到i-1元素的后面->结束
bool ListFrontInsert(LinkList L,int i,ElemType InsertVal)
{
LinkList p = GetElem(L,i-1);
if(p==NULL)
return false;
LinkList q=(LinkList) malloc(sizeof (LNode*));//为新结点申请空间
q->data=InsertVal;
q->next=p->next;
p->next=q;
}

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)