数据结构——线性表(数组,链表)

今天又是学习数据结构的一天。(mooc浙大数据结构的重点笔记)

线性表: 由同类数据元素构成有序序列的线性元素。元素的个数成为表长,表中没有元素时成为空表。起始位置为表头,结束位置为表尾。

线性表的基本操作:

  1. List MakeEmpty():初始化一个空线性表L。
  2. ElementType FindKth(int k, List L):根据位序k,返回相应的元素;
  3. int Find(ElementType X, List L):在线性表中查找X第一次出现的位置;
  4. void Insert(ElementType X, List L):在位序i前插入一个新元素X;
  5. void Delete(int i, List L):删除指定位序i的元素;
  6. int length(List L):返回线性表的长度n;

一、数组实现方式:
利用数组的连续储存空间顺序存放线性表的各元素
在这里插入图片描述

typedef int Position;
typedef struct LNode *List;
struct LNode {
    ElementType Data[MAXSIZE];
    Position Last;
};
 
/* 初始化 */
List MakeEmpty()
{
    List L;
 
    L = (List)malloc(sizeof(struct LNode));
    L->Last = -1;
 
    return L;
}

/* 查找位序元素 */
ElementType FindKth(int k, List L) {
	return L->Data[k];
}
 
/* 查找 */
#define ERROR -1
 
Position Find( List L, ElementType X )
{
    Position i = 0;
 
    while( i <= L->Last && L->Data[i]!= X )
        i++;
    if ( i > L->Last )  return ERROR; /* 如果没找到,返回错误信息 */
    else  return i;  /* 找到后返回的是存储位置 */
}
 
/* 插入 */
bool Insert( List L, ElementType X, Position P ) 
{ /* 在L的指定位置P前插入一个新元素X */
    Position i;
 
    if ( L->Last == MAXSIZE-1) {
        /* 表空间已满,不能插入 */
        printf("表满"); 
        return false; 
    }  
    if ( P<0 || P > L->Last+1 ) { /* 检查插入位置的合法性 */
        printf("位置不合法");
        return false; 
    } 
    for( i = L->Last; i >= P; i-- )
        L->Data[i+1] = L->Data[i]; /* 将位置P及以后的元素顺序向后移动 */
    L->Data[P] = X;  /* 新元素插入 */
    L->Last++;       /* Last仍指向最后元素 */
    return true; 
} 
 
/* 删除 */
bool Delete( List L, Position P )
{ /* 从L中删除指定位置P的元素 */
    Position i;
 
    if( P<0 || P>L->Last ) { /* 检查空表及删除位置的合法性 */
        printf("位置%d不存在元素", P ); 
        return false; 
    }
    for( i = P+1; i <= L->Last; i++ )
        L->Data[i-1] = L->Data[i]; /* 将位置P+1及以后的元素顺序向前移动 */
    L->Last--; /* Last仍指向最后元素 */
    return true;   
}

/* 长度 */
int Length(List L) {
	return L->Last + 1;
}


二、链表实现:
在这里插入图片描述
插入操作:假如在p后面插入s
1.找到p节点
2.在s->Next中存入p的下一个节点的地址p->Next
3.把s的地址存到p->Next中,s成为p的下一个节点
在这里插入图片描述
删除操作:
1.用p指向要被删除的s节点前的节点
2.在p->Next里面存入s的下一个节点地址s->Next
3.释放s的空间free
在这里插入图片描述

typedef struct LNode *PtrToLNode;
struct LNode {
    ElementType Data;
    PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;


/* 初始化 */
List MakeEmpty()
{
    List L;
 
    L = (List)malloc(sizeof(struct LNode));
    L->Next = -1;
 
    return L;
}

#define ERROR NULL

/*按序号查找*/
ElementType Kth(int k, List L) {
	List p = L;
	int i = 0;
	while (p != null && i < k) {
		p = p->Next;
		i++;
	}
	if (i == k) return p->Data;
	else return ERROR;
}

/* 按值查找查找 */
Position Find( List L, ElementType X )
{
    Position p = L; /* p指向L的第1个结点 */
 
    while ( p && p->Data != X )
        p = p->Next;
 
    /* 下列语句可以用 return p; 替换 */
    if ( p )
        return p;
    else
        return ERROR;
}
 
/* 带头结点的插入 */
bool Insert( List L, ElementType X, Position P )
{ /* 这里默认L有头结点 */
    Position tmp, pre;
 
    /* 查找P的前一个结点 */        
    for ( pre=L; pre && pre->Next != P; pre = pre->Next ) ;            
    if ( pre == NULL ) { /* P所指的结点不在L中 */
        printf("插入位置参数错误\n");
        return false;
    }
    else { /* 找到了P的前一个结点pre */
        /* 在P前插入新结点 */
        tmp = (Position)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
        tmp->Data = X; 
        tmp->Next = P;
        pre->Next = tmp;
        return true;
    }
}
 
/* 带头结点的删除 */
bool Delete( List L, Position P )
{ /* 这里默认L有头结点 */
    Position tmp, pre;
 
    /* 查找P的前一个结点 */        
    for ( pre=L; pre && pre->Next != P; pre = pre->Next ) ;            
    if ( pre == NULL || P == NULL) { /* P所指的结点不在L中 */
        printf("删除位置参数错误\n");
        return false;
    }
    else { /* 找到了P的前一个结点pre */
        /* 将P位置的结点删除 */
        pre->Next = P->Next;
        free(P);
        return true;
    }
}

/*表长*/
int Length(List L) {
	List p = L;
	int ans = 0;
	while (p) {
		p = p->Next; /* p指向表的第一个节点 */
		ans++;
	}
	return ans;
}

有错误欢迎指出~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值