算法与数据结构c语言版基本知识总结

线性表

一.顺序表

1.顺序表的定义与基本使用

算法与数据结构c语言版基本知识总结_第1张图片

/*基本定义*/
#define Maxsize maxlen //maxlen表示线性表可能的最大数据元素数目
typedef int elmentype //elemtype表示数据元素类型,此处定义为int
typedef struct 
{
     elemtype data[Maxsize]; //存放线性表元素的数组    
      int len;       //表示线性表的长度
 }sqlist;
 
 /*两种使用方法*/
sqlist  L;//第一种使用方法,L就是顺序表
L.data[i]//顺序表中的第i个元素
L.len//顺序表的长度

sqlist *sq;//第二种使用方法,  定义指向顺序表的指针
sq=(sqlist *)malloc(sizeof(sqlist));//因为是指针,所以需要开辟空间
sq->data[i];//顺序表中的第i个元素
sq->len;//顺序表的长度

2.顺序表的基本操作

构造一个空的顺序线性表

void initlist(sqlist *L)
{ L-> len=0; }
//算法时间复杂度:O(1)

插入算法

思路步骤(4)
1.判断线性表的存储空间是否已满,若已满,则进行“溢出”处理(判满)
2.检查i值是否超出允许的范围(1≤i≤len+1),若超出,则进行“超出”处理(判超)
3.如果上述条件都允许,则将最后一个元素到第i个元素依次向后移动一个位置(移动)
4.将新的数据元素写到第i个位置上,线性表长度+1(写入)

int insert(sqlist *L,int i,elemtype x)//将x插入第i个位置
{
    int j;
    if(L->len==Maxsize)//顺序表长度等于存储最大长度则满
    {
    printf("溢出!\n");
    return 0;
    }
    else if(i<1||i>L->len+1)//判断i是否超出范围
    {
    printf("插入位置不正确\n");
    return 0;
    }
    else//把第i个元素和它后面的元素后移
    {
      for(j=L->len;j>i-1;j--)
        L->data[j]=L->data[j-1];
       L->data[i-1]=x;//把新元素写入下标为i-1的位置
       L->len++;//顺序表长度+1
       return(1); 
}
//算法的最坏情况(插入第一个位置 i=1)时间复杂度:O(n)
//算法的最好情况(插入最后一个位置 i = L->len+1)  时间复杂度:O(1)

删除算法

思路步骤(3)(类似插入)
判断i值是否超出允许的范围(1≤i≤len),若是,则进行“超出范围”处理;
否则,保存第i个元素的值;
将第i个元素后的所有元素依次向前移动一个位置;
线性表长度减1,删除成功

int delete(sqlist *L,int i)//将x插入第i个位置
{
    int j;
    if(i<1||i>L->len+1)//判断i是否超出范围
    {
    printf("删除位置不正确\n");
    return 0;
    }
    else//把第i个元素和它后面的元素前移
    {
      for(j=i;j<L->len-1;j--)
        L->data[j-1]=L->data[j];
       L->data[i-1]=x;//把新元素写入下标为i-1的位置
       L->len++;//顺序表长度+1
       return(1); 
}
//算法的最坏情况(删除第一个位置 i=1)时间复杂度:O(n)
//算法的最好情况(删除最后一个位置 i = L->len)  时间复杂度:O(1)

求线性表的长度

  int lenth(sqlist *L)
  {
       int  len;
       len=L->len;        
       return(len);   //返回线性表的长度 
}

遍历查找

int locate(sqlist *L,elemtype x)//查找顺序表中的x
{
  for(int i=0;i<L->len;i++){//遍历
     if(x==L->data[i])
         break;
  }
  if(i<L->len)
      return (i+1);//x是该顺序表的第i个元素
  else//顺序表中不存在x
     return 0;
}

二.链表

1.单链表的定义与基本使用

在这里插入图片描述
算法与数据结构c语言版基本知识总结_第2张图片
头结点的指针域存储链表首结点的地址
如果头结点的指针域为“空”(如图b),即L->next==NULL,表示该链表为空表

/*基本定义*/
typedef char elemtype;
typedef struct node
{   elemtype   data;//数据域
     struct node *next;//指针域
}Lnode,* linklist;

 /*两种使用方法*/
 Lnode  *L;    与    linklist  L;  等价
 
 linklist  h,p; //第一种,h头结点,p结点
 p.data;
 p.next;
 
 
Lnode  *h,*p;//第二种使用方法,  定义指向头结点(h)和结点(p)的指针
  p=(Lnode *)malloc(sizeof(Lnode));
  h=(Lnode *)malloc(sizeof(Lnode));
 (*p).data=p->data;//两种表示方法
 (*p).next=p->next;

2.单链表的基本操作

头插法创建带头结点的单链表

#include 
#include 
typedef char elemtype;
typedef struct node
{  
    elemtype data;
    struct node *next;
    }Lnode;
#define lEN sizeof(Lnode)//定义结点长度
Lnode *creat()
{
   Lnode *p,*head;
   head=(Lnode *)malloc(LEN);//头结点
   head->next=NULL;
   while(1)
   {
     p=(Lnode *)malloc(LEN);//申请一个新结点
     scanf("%c",&p->data);//数据域赋值
     p->next=h->next;//修改新结点的指针域
     h->next=p;//将新结点设置为第一个结点
     printf("是否继续(y/n):");
     if(getchar()=='n')
       break;
    }
    return(head);
 }

尾插法创建带头结点的单链表

#include
#include
typedef char elemtype;
typedef struct node{
elemtype data;
struct node *next;
}Lnode;
#define LEN sizeof(Lnode)//定义结点长度
Lnode *creat()
{
  Lnode *p,*tail,*head;
  tail=head=(Lnode *)malloc(LEN);//头结点
  head->next=NULL;
  while(1)
  {
    p=(Lnode *)malloc(LEN);
    scanf("%c",&p->data);//数据域赋值
    
    tail->next=p;
    tail=p;
    tail->next=NULL;
    
    printf("是否继续?(y/n):");
    if(getchar()=='n')
       break;
       }
       return(head);
 }

求带头结点的单链表的长度

int length(Lnode *h)
{
   Lnode *p;
   int i=0;
   p=h->next;
   while(p!=NULL)
   {
     ++i;
     p=p->next;
   }
   return(i);
 }

单链表插入算法

算法与数据结构c语言版基本知识总结_第3张图片

int insert(Lnode *h,int i,elemtype x)
{
   Lnode *p,*s;
   int j;
   p=H->next;
   j=1;
   while(P&&j<i)//寻找第i个结点
   {
      j++;
      p=p->next;
   }
   if(j==i)
   {
       s=(Lnode *)malloc(sizeof(Lnode));
       s->data=x;
       s->next=p->next;
       p->next=s;
       return(1);
    }
    else
       return(0);
   }

单链表删除算法

算法与数据结构c语言版基本知识总结_第4张图片

//删除单链表的第i个结点
int dele(Lnode *head,int i)
{
   Lnode *p,*q;
   int j=1;
   p=head->next;
   if(p==NULL)//空表,无法删除
      return 0;
   while(p&&(j<i-1))
   {
     j++;
     p=p->next;
    }//寻找i-1个结点
    if(j<i-1)//第i-1个结点不存在
       return 0;
    else if(p->next==NULL)
           return 0; //第i个结点不存在
     q=p->next;
     p->next=q->next;
     free(q);
     return 1;
    }

查找单链表中数据域为x的结点

Lnode *locate(Lnode *h,elemtype x)
{
   Lnode *p;
   p=h->next;//p为单链表的第一个结点
   while(p!=NULL&&p->data!=x)//扫描整个单链表,查找值x的结点
   p=p->next;//未找到,指针继续向后移扫描
   return(p);
 }

读取单链表中指定位置的元素

插入算法中包括此l类似算法思路

//读取单链表中的第i个元素
Lnode *get(Lnode *h,int i)
{
  int j=1;
  Lnode *p=h->next;
  
  while(p&&j<i)//移动指针p,直至p为空或者p指向第i个元素
  {
    p=p->next;
    j++;
  }
  if(i==j)
     return(p)
  else 
     return NULL;
 }

2.循环链表(看)

定义:单链表中最后一个结点的链域值不是NULL,而是指向头结点,整个表形成一个环

特点:从表中任意结点出发均可找到表中其它的结点
操作与单链表基本一致,循环结束条件不同
带头结点的单链表:p->nextNULL
带头结点的单循环链表:p->next
head
在这里插入图片描述

3.双向链表(看)

每一个结点中有两个指针域
一个指向直接后继,另一个指向直接前趋
这样的链表称为双向链表
结点描述如下:
在这里插入图片描述

typedef struct dulnode
  {   elemtype  data;
      struct dulnode *next,*prior;
  }Dulnode; 

算法与数据结构c语言版基本知识总结_第5张图片

双向循环链表的插入算法

算法与数据结构c语言版基本知识总结_第6张图片

//改变指针链接的语句有(在双向循环链表结点p之前插入结点s
)
① s->prior=p->prior;
② p->prior->next=s;
③ s->next=p;
④ p->prior=s;

双向循环链表删除算法

算法与数据结构c语言版基本知识总结_第7张图片

//改变指针链接的语句有
p->prior->next=p->next;
p->next->prior=p->prior;

你可能感兴趣的:(算法与数据结构c语言版基本知识总结)