数据结构(寒假小结)——2.2线性表之单链表

本文详细介绍了单链表的概念、基本定义、相关名词及其存储结构,并提供了单链表的基本运算实现,包括建表、初始化、求表长、查找、插入、删除及销毁等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、本节学习要点:

2、链表的引入:



顺序表和链表的比较:

3、单链表的基本定义:

单链表:每个结点有两部分信息:数据域,存放结点的值(内容);指针域(亦称链域),存放结点后继的地址(或位置)。由于每个结点只有一个链域,故得名单链表。


4、单链表的相关名词:

1.结点:结点=数据域+指针域;

2.空指针:不指向任何结点(常用NULL^表示)

3.头指针:单链表第一个结点的地址;

    1)单链表由头指针唯一确定;
     2)头指针具有标识单链表的作用;
     3)单链表常用头指针命名,如head表

4.头结点:单链表第一个结点前人为增加的结点,不存放数据;

     1)作用:简化链表操作,统一空表与非空表
     2)有时可将头结点看成0号结点

5.结点的存储结构

typedef int datatype;	//结点数据类型,假设为int
typedef struct node * pointer; //结点指针类型
struct node {			//结点结构
   datatype data;//数据域
   pointer next;//指针域
};
typedef pointer lklist; //单链表类型,即头指针类型

5、单链表的基本运算:

1.建表:头插法、尾插法。

头插法:


lklist creat() {		//头插法建表,有头结点
  lklist head; pointer s; char ch;
  head=new node; 		//生成头结点
  head->next=NULL;
  while(cin>>ch,ch!='$') {//输入并检测结束
    s=new node;			//生成新结点
    s−>data=ch;			//装入数据
    s−>next=head−>next;
    head−>next=s;		//插到头结点后
  }
  return  head;
}
尾插法:

lklist creat() { //尾插法建表,无头结点的情况
  pointer head,rear,s; char ch;
  head=NULL;	//链表初始值为空
  rear=NULL;		//尾指针初值也为空
  cin>>ch;            //读入第一个节点值
  while(ch!=’$’) {  //检测是否结束
    s=new node;	 s−>data=ch; //生成新结点
    if(head==NULL) head=s; //生成第一个节点
    else rear->next=s;
    rear=s;	   //尾指针指向新的表位
    cin>>ch;
  }
  if(rear!=NULL) rear−>next=NULL;//尾结点的后继为空
  return head;
}<pre name="code" class="cpp">lklist creat() { //尾插法建表,有头结点的情况下
  pointer head,rear,s; char ch;
  head=new node;	//生成头结点
  rear=head;		//尾指针初值
  while(cin>>ch,ch!=’$’) {  //读入并检测结束
    s=new node;	 s−>data=ch; //生成新结点
    rear−>next=s; rear=s;	   //插入表尾,改尾指针
  }
  rear−>next=NULL;	//尾结点的后继为空
  return head;
}

 

2.初始化:

lklist initlist() {
   pointer head;
   head=new node;
   head−>next=NULL;
   return head;
} 
3.求表长:
int length(lklist L) {
  int j; pointer p;
  j=0; p=L->next;	//从首结点开始
  while(p!=NULL) {	//逐点检测、计数
    j++; p=p->next;
  }		
 return j;

4.按序号查找:

pointer get(lklist head, int i) { //0<=i<=n
  int j;
  pointer p;
  if(i==0) return head;//0号结点为头结点
  if(i<0) return NULL; //位置非法,无此结点
  j=0;			//计数器
  p=head->next;		//从首结点开始搜索
  while(p!=NULL) {
    j++;if(j==i) break;
    p=p−>next;		//未到第i个点,继续往后搜索
  }
  return p;		//含找到、未找到两种情况
				//未找到时p自动为NULL
}

5.按值查找

pointer locate(lklist head,datatype x) {
  pointer p;
  p=head−>next;	//从首结点开始搜索
  while(p!=NULL) {
    if(p−>data==x) break;
    p=p−>next;	//到下一个点
  }
  return p; 		//含找到、未找到两种情况
}

6.插入:


int insert(lklist head,datatype x,int i){
  pointer q,s;
  q=get(head,i−1);	//找第i−1个点
  if(q==NULL)   //无第i−1点,即i<1或i>n+1时
    {cout<<”非法插入位置!\n”;return 0;}
  s=new node;		//生成新结点
  s−>data=x;
  s−>next=q−>next;  //新结点的后继是原第i个点
  q−>next=s;		//原第i−1个点的后继是新结点
  return 1;		//插入成功
}

等效插入:


int insert(lklist head,datatype x,int i){
  pointer p,s;
  p=get(head,i−1);	//找第i−1个点
  if(p==NULL)   //无第i−1点,即i<1或i>n+1时
    {cout<<”非法插入位置!\n”;return 0;}
  s=new node;		//生成新结点
  s−>data=p−>data;
  s−>next=p−>next;
  p−>data=x; 
  p−>next=s;
  return 1;		//插入成功
}

7.删除:


int delete(lklist head,int i) {
  pointer p,q;
  q=get(head,i−1);	//找待删点的直接前趋
  if(q==NULL || q−>next==NULL){ //即i<1或i>n时
    cout<<”非法删除位置!\n”;
    return 0;
  }
  p=q−>next;			//保存待删点地址
  q−>next=p−>next;	//修改前趋的后继指针
  delete p;			//释放结点
  return 1;		
8.销毁:
void destroy(lklist head) { //删除所有结点
  pointer p,q;
  p=head;
  while(p!=NULL) {
    q=p->next;	      //保存待删点后继
    delete p;        //释放空间
    p=q;
  }
6、顺序表和单链表的比较:

PS:

1.若线性表需频繁查找却很少进行插入和删除操作,或其操作和元素在表中的位置密切相关时,宜采用顺序表作为存储结构;若线性表需频繁插入和删除时,则宜采用链表做存储结构。
2.当线性表中元素个数变化较大或者未知时,最好使用链表实现;而如果用户事先知道线性表的大致长度,使用顺序表的空间效率会更高


如果有错误请大家指出,共同学习共同进步!更多百度百科奋斗奋斗


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值