数据结构复习笔记-------线性表的链式存储

1.线性表的链式存储

知识点 1链表:任意的存储结构(连续与否均可以)
知识点 2链表中数据元素的逻辑顺序和存储顺序可能不一致
知识点 3

结点结构定义

typedef struct node{

       Datatype data;

       struct node *next;

}Node;

知识点 4

1.无头结点的单链表

(1) 无头结点的单链表非空链表 

(2) first 空表 first  NULL 无头结点的单链表为空的条件是first=NULL

2.有头结点的单链表

(1) 有头结点的单链表非空链表  

(2) first 空表 first    

有头结点的单链表为空的条件是  first->next=NULL

头结点的作用:简化运算

知识点5

取数据域的值 p->data

取指针域的值p->next

工作指针后移P=P->next

2.有头结点的单链表的算法

2.1 初始化空表 T(n)=O(1)

Node *Init_linklist()
{
   Node * first;
   first=(Node *)malloc(sizeof(Node));
   first->next=NULL;
   return first;
}

2.2单链表的遍历算法 T(n)=O(n)

void print_linklist(Node *first)
{
    Node *p;
    p=first->next;
    while(p)
    {
         printf("%d",p->data);
         p=p->next;
    }
}

2.3求单链表的长度的算法 T(n)=O(n)

int length_linklist(Node *first)
{
    Node *p;
    int j=0;
    p=first;
    while(p->next)
    {
         j++;
         p=p->next;
    }
}

2.4找i位置的数据元素 T(n)=O(n)

int  Get(Node *first ,int i,datatype *ptr)
{
   Node *p;
   int j=0;
   p=first;
   while(p->next &&j<i)
  {
     p=p->next;
     j++;
  }
  if(j==i) { 
      *ptr=p->data;
       return 1;
           }
  else   {
      printf("位置异常"); 
      return 0;
         }
}

2.5插入 T(n)=O(n)

int  insert_linklist(Node *first ,int i,datatype x)
{
   Node *p,*s;
   int j=0;
   p=first;
   while(p->next &&j<i-1)
  {
     p=p->next;
     j++;
  }
  if(j==i-1) 
 { 
       s=(Node *)malloc(sizeof(Node));
       s->data=x;
       s->next=p->next;
       p->next=s;
   }
  else  {printf("位置异常"); 
            return 0;}
​
}

2.6头插法构造单链表 T(n)=O(n)

Node * Create_linklist(datatype r[],int n)
{
   Node *first,*s;
   first=(Node *)malloc(sizeof(Node));
   first->next=NULL;
   for(i=0;i<n;i++)
   {
       s=(Node *)malloc(sizeof(Node));
       s->data=r[i];
       s->next=first->next;
       first->next=s;
    }
   return first;
​
}

2.7尾插法构造单链表 T(n)=O(n)

Node * Create_linklist(datatype r[],int n)
{
   Node *first,*rear,*s;
   int i;
   first=rear=(Node *)malloc(sizeof(Node));
    for(i=0;i<n;i++)
   {
       s=(Node *)malloc(sizeof(Node));
       s->data=r[i];
       rear->next=s;
       rear=s;
    }
   rear->next=NULL;
   return first;
​
}

2.8删除 T(n)=O(n)

int  delete_linklist(Node *first ,int i,datatype *ptr)
{
   Node *p,*s;
   int j=0;
   p=first;
   while(p->next &&j<i-1)
  {
     p=p->next;
     j++;
  }
  if(j==i-1 && p->next) 
 { 
      q=p->next;
      p->next=q->next;
      *ptr=q->data;
      free(q);
      return 1;
   }
  else  {printf("位置异常"); return 0;}
​
}

2.9按值查找算法 T(n)=O(n)

int Locate_linklist(Node *first,datatype x)
{
    Node *p;
    int j;
    p=first->next;
    j=1;
    while(p)
    {
        if(p->data==x) 
        {
            return j;
        }
        p=p->next;
        j++;
    }
    return 0;
}

2.10已知两个单链表head1和head2,把head2连接在head1后面。Head1长度为m,head2长度为n,时间复杂度为O(m)

Node *connect(Node *head1,Node *head2)
{
    Node *p;
    p=head1;
    while(p->next)
     p=p->next;
    p->next=head2->next;
    free(head2);
    return head1;   
}

2.11将两个非递减有序的单链表,合并为一个非递减有序的单链表 O(m+n)

Node *connect1(Node head1,Node head2)
{
    p=head1->next;
    q=head2->next;
    head1->next=NULL;
    rear=head1;
    while(p&&q)
    {
        if(p->data<=q->data)
        { t=p;p=p->next;
          rear->next=t;
          rear=t;           
        }
        else 
        {
            t=q;q=q->next;
            rear->next=t;
            rear=t; 
        }
    }
    if(p) rear->next=p;
    if(q) rear->next=q;
    free(head2);
    return head1;
}

2.12、将两个非递减有序的单链表,合并为一个非递增有序的单链表 O(m+n)

Node *connect1(Node head1,Node head2)
{
    p=head1->next;
    q=head2->next;
    head1->next=NULL;
    while(p&&q)
    {
        if(p->data<=q->data)
        { t=p;p=p->next;
          t->next=first->next;
          first->next=t;            
        }
        else 
        {
            t=q;q=q->next;
            t->next=first->next;
            first->next=t;
        }
    }
    while(p) 
        {
            t=p;p=p->next;
            t->next=first->next;
            first->next=t;
        }
    while(q) 
        {
            t=q;q=q->next;
            t->next=first->next;
            first->next=t;
        }
    free(head2);
    return head1;
}

2.13、 单链表的逆置算法 T(n)=O(n)

void reverse(Node *first)
{
    Node *p,*q;
    p=first->next;
    first->next=NULL;
    while(p)
    {
        q=p->next;
        p->next=first->next;
        first-next=p;
        p=q;
    }
}

2.14、判断单链表是否非递减有序 O(n)

int increase(Node *first)
{
    Node *p,*t;
    t=first->next;
    p=t->next;
    while(p && t)
    {
        if(t->data>p->data) return 0;
        t=p;
        p=p->next;  
    }
    return 1;
}

2.15、删除单链表中所有值为x的数据元素。 O(n)

void delete_x(Node *first ,datatype x)
{
    Node *p,*t;
    p=first->next;
    t=first;
    while(p)
    {
        if(p->data==x)
        {
            t->next=p->next;
            free(p);
            p=t->next;
        }
        else{
            t=p;
            p=p->next;
        }
    }   
}

2.16、单链表排序(头插法)

void sort_linklist(Node *first)
{
    Node *p,*t,*q;
    p=first->next->next;
    first->next->next=NULL;
    while(p)
    {   t=p;
        p=p->next;
        q=first;
        while(q->next&&q->next->data<t->data)
        {
            q=q->next;
        }
        t->next=q->next;
        q->next=t;      
    }
    
}

3.顺序表和单链表的比较

顺序表单链表
按位置查找O(1)随机存取O(n)顺序存取
按值查找O(n)平均比较(n+1)/2O(n)平均比较(n+1)/2
插入O(n)平均移动n/2 效率低O(n)不移动元素修改指针,效率高
删除O(n)平均移动(n-1)/2 效率低O(n)不移动元素修改指针,效率高

4.线性表的存储结构

知识点1:循环单链表  first 循环单链表从任意一个结点出发都能遍历整个单链表。
知识点2 

 循环单链表first

单链表p指向尾结点的条件 p->next=NULL

循环单链表p指向尾结点的条件 p->next=first

知识点3

循环单链表  first 头指针指示的单循环链表:

表头位置 插入O(1) 删除O(1)

表尾位置 插入O(n)    删除O(n)

知识点4

存储密度:(数据本身占得存储量)/(结点所占的存储量)

顺序表:存储密度=1;

链表:存储密度<1

知识点5

静态链表工作指针j后移的语句

j=r[j].next ;

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱编程的小美女

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

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

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

打赏作者

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

抵扣说明:

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

余额充值