文章目录
1. 线性表
2. 顺序表(顺序存储结构) 2.1 定义(存储结构代码描述) 2.2 插入元素
2.3 删除元素
2.4 完整代码 2.5 动态分配数组
3. 单链表(链式存储结构) 3.1 定义(存储结构代码描述) 3.2 单链表的读取 3.3 单链表的插入 3.4.0 插入第i位 3.3.1 头插法 3.3.2 尾插法
3.4 单链表的查找
3.5 单链表的删除 3.6 完整代码
4. 双链表 4.1 定义 4.2 双链表的插入 4.2.0 插入第i位 4.2.1 头插法 4.2.2 尾插法
4.3 双链表的查找 4.4 双链表的删除
1. 线性表
1.1 定义
1.2 特点
2. 顺序表(顺序存储结构)
2.1 定义(存储结构代码描述)
线性表的顺序存储:指的是用一段地址连续的存储单元 依次存储线性表的数据结构 使用一维数组 来实现顺序存储结构 顺序表存储的结构代码如下:
# define MAXSIZE 20
typedef int ElemType;
typedef struct
{
ElemType data[ MAXSIZE] ;
int length;
} SqList;
优缺点 数组长度和线性表长度的区别 数组长度是存储线性表空间的长度 线性表的长度是线性表中数据元素的个数,随着线性表插入和删除的进行,量是变化的
2.2 插入元素
2.2.1 图形演示
2.2.2 代码表示
在L中第i个位置之前插入新的数据元素e,L的长度加1
bool ListInsert ( SqList& L, int i, ElemType e)
{
if ( i< 1 || i> L. length + 1 )
return false;
if ( L. length >= MaxSize)
return false;
for ( int j = L. length; j >= i; j-- )
{
L. data[ j] = L. data[ j - 1 ] ;
}
L. data[ i - 1 ] = e;
L. length++ ;
return true;
}
Status ListInsert ( SqList * L, int i, ElemType e)
{
if ( L-> length == MAXSIZE)
return ERROR;
if ( i < 1 || i > L-> length + 1 )
return ERROR;
if ( i <= L-> length)
{
for ( int k = L-> length; k >= i; k-- )
L-> data[ k] = L-> data[ k- 1 ] ;
}
L-> data[ i- 1 ] = e;
L-> length++ ;
return OK;
}
2.3 删除元素
2.3.1 图形演示
2.3.2 代码表示
bool ListDelete ( SqList& L, int i, ElemType& e)
{
if ( i< 1 || i> L. length)
return false;
if ( L. length == 0 )
{
return false;
}
e = L. data[ i - 1 ] ;
for ( int j = i; j < L. length; j++ )
{
L. data[ j - 1 ] = L. data[ j] ;
}
L. length-- ;
return true;
}
Status ListDelete ( SqList * L, int i, ElemType * e)
{
if ( L-> length == 0 )
return ERROR;
if ( i < 1 || i > L-> length)
return ERROR;
* e = L-> data[ i- 1 ] ;
if ( i< L-> length)
{
for ( int k = i; k < L-> length; k++ )
L-> data[ k- 1 ] = L-> data[ k] ;
}
L-> length-- ;
return OK;
}
2.4 完整代码
# include <stdio.h>
# include <stdlib.h>
# define MaxSize 50
typedef int ElemType;
typedef struct
{
ElemType data[ MaxSize] ;
int length;
} SqList;
bool ListInsert ( SqList& L, int i, ElemType e)
{
if ( i< 1 || i> L. length + 1 )
return false ;
if ( L. length >= MaxSize)
return false ;
for ( int j = L. length; j >= i; j-- )
{
L. data[ j] = L. data[ j - 1 ] ;
}
L. data[ i - 1 ] = e;
L. length++ ;
return true ;
}
bool ListDelete ( SqList& L, int i, ElemType& e)
{
if ( i< 1 || i> L. length)
return false ;
if ( L. length == 0 )
{
return false ;
}
e = L. data[ i - 1 ] ;
for ( int j = i; j < L. length; j++ )
{
L. data[ j - 1 ] = L. data[ j] ;
}
L. length-- ;
return true ;
}
int LocateElem ( SqList L, ElemType e)
{
int i;
for ( i = 0 ; i < L. length; i++ )
{
if ( L. data[ i] == e)
return i + 1 ;
}
return 0 ;
}
void PrintList ( SqList& L)
{
for ( int i = 0 ; i < L. length; i++ )
{
printf ( "%3d" , L. data[ i] ) ;
}
printf ( "\n" ) ;
}
int main ( )
{
SqList L;
bool ret;
ElemType del;
L. data[ 0 ] = 1 ;
L. data[ 1 ] = 2 ;
L. data[ 2 ] = 3 ;
L. length = 3 ;
ret = ListInsert ( L, 2 , 60 ) ;
if ( ret)
{
printf ( "插入成功\n" ) ;
PrintList ( L) ;
}
else
{
printf ( "插入失败\n" ) ;
}
printf ( "\n" ) ;
ret = ListDelete ( L, 1 , del) ;
if ( ret)
{
printf ( "删除成功\n" ) ;
printf ( "删除元素值为%d\n" , del) ;
PrintList ( L) ;
}
else
{
printf ( "删除失败\n" ) ;
}
printf ( "\n" ) ;
int elem_pos;
elem_pos = LocateElem ( L, 60 ) ;
if ( elem_pos)
{
printf ( "查找成功\n" ) ;
printf ( "元素位置为%d\n" , elem_pos) ;
}
else
{
printf ( "查找失败\n" ) ;
}
return 0 ;
}
2.5 动态分配数组
3. 单链表(链式存储结构)
3.1 定义(存储结构代码描述)
头指针:指链表指向第一个结点的指针。如果链表有头结点,那么头结点就是链表第一个节点,则头指针则是指向头结点的指针 。 头指针具有标志作用,所以常用头指针冠以链表的名字 无论链表是否为空,头指针均不为空。头指针是链表的必要元素 ,头结点不一定是链表必需元素 这里L表示头指针 ,L->next表示头结点,L->next = NULL 表示头结点为空 一般单链表名称是头指针
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode * next;
} LNode, * LinkList;
3.2 单链表的读取
Status GetElem ( LinkList L, int i, ElemType * e)
{
int j;
LinkList p;
p = L-> next;
j = 1 ;
while ( p && j< i)
{
p = p-> next;
++ j;
}
if ( ! p || j> i )
return ERROR;
* e = p-> data;
return OK;
}
3.3 单链表的插入
3.4.0 插入第i位
bool ListFrontInsert ( LinkList L, int i, ElemType e)
{
LinkList p = GetElem ( L, i - 1 ) ;
if ( p = NULL )
{
return false;
}
LinkList s = ( LNode* ) malloc ( sizeof ( LNode) ) ;
s-> data = e;
s-> next = p-> next;
p-> next = s;
return true;
}
3.3.1 头插法
插入链表的基本操作
s-> next = p-> next;
p-> next = s;
L应该理解为头指针或者是头结点,L->next是第1个结点(就是a1),这样和程序s->next = L->next就吻合了。头插法插入的节点在头结点和第1个结点之间 。
LinkList CreateList1 ( LinkList& L)
{
LNode* s;
int x;
L = ( LinkList) malloc ( sizeof ( LNode) ) ;
L-> next = NULL ;
scanf ( "%d" , & x) ;
while ( x != 9999 )
{
s = ( LNode* ) malloc ( sizeof ( LNode) ) ;
s-> data = x;
s-> next = L-> next;
L-> next = s;
scanf ( "%d" , & x) ;
}
return L;
}
3.3.2 尾插法
LinkList CreateList2 ( LinkList& L)
{
int x;
L = ( LinkList) malloc ( sizeof ( LNode) ) ;
LNode* s, * r = L;
scanf ( "%d" , & x) ;
while ( x != 9999 )
{
s = ( LNode* ) malloc ( sizeof ( LNode) ) ;
s-> data = x;
r-> next = s;
r = s;
scanf ( "%d" , & x) ;
}
r-> next = NULL ;
return L;
}
3.4 单链表的查找
3.4.1 按序号查找
这里的p是一个动态的结点
LNode* GetElem ( LinkList L, int i)
{
int j = 1 ;
LNode* p = L-> next;
if ( i == 0 )
{
return L;
}
if ( i < 1 )
{
return NULL ;
}
while ( p && j < i)
{
p = p-> next;
j++ ;
}
return p;
}
3.4.2 按值查找
p可以理解为是地址
LinkList LocateElem ( LinkList L, ElemType e)
{
LinkList p = L-> next;
while ( p != NULL && p-> data != e)
{
p = p-> next;
}
return p;
}
3.5 单链表的删除
bool ListDelete ( LinkList L, int i)
{
LinkList p = GetElem ( L, i - 1 ) ;
if ( p = NULL )
{
return false;
}
LinkList q = p-> next;
if ( q == NULL )
{
return false;
}
p-> next = q-> next;
free ( q) ;
q = NULL ;
return true;
}
3.6 完整代码
# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
# include <stdlib.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode * next;
} LNode, * LinkList;
LinkList CreateList1 ( LinkList& L)
{
LNode* s;
int x;
L = ( LinkList) malloc ( sizeof ( LNode) ) ;
L-> next = NULL ;
scanf ( "%d" , & x) ;
while ( x != 9999 )
{
s = ( LNode* ) malloc ( sizeof ( LNode) ) ;
s-> data = x;
s-> next = L-> next;
L-> next = s;
scanf ( "%d" , & x) ;
}
return L;
}
LinkList CreateList2 ( LinkList& L)
{
int x;
L = ( LinkList) malloc ( sizeof ( LNode) ) ;
LNode* s, * r = L;
scanf ( "%d" , & x) ;
while ( x != 9999 )
{
s = ( LNode* ) malloc ( sizeof ( LNode) ) ;
s-> data = x;
r-> next = s;
r = s;
scanf ( "%d" , & x) ;
}
r-> next = NULL ;
return L;
}
LNode* GetElem ( LinkList L, int i)
{
int j = 1 ;
LNode* p = L-> next;
if ( i == 0 )
{
return L;
}
if ( i < 1 )
{
return NULL ;
}
while ( p && j < i)
{
p = p-> next;
j++ ;
}
return p;
}
LinkList LocateElem ( LinkList L, ElemType e)
{
LinkList p = L-> next;
while ( p != NULL && p-> data != e)
{
p = p-> next;
}
return p;
}
bool ListFrontInsert ( LinkList L, int i, ElemType e)
{
LinkList p = GetElem ( L, i - 1 ) ;
if ( p = NULL )
{
return false;
}
LinkList s = ( LNode* ) malloc ( sizeof ( LNode) ) ;
s-> data = e;
s-> next = p-> next;
p-> next = s;
return true;
}
bool ListDelete ( LinkList L, int i)
{
LinkList p = GetElem ( L, i - 1 ) ;
if ( p = NULL )
{
return false;
}
LinkList q = p-> next;
if ( q == NULL )
{
return false;
}
p-> next = q-> next;
free ( q) ;
q = NULL ;
return true;
}
void PrintList ( LinkList L)
{
L = L-> next;
while ( L != NULL )
{
printf ( "%3d" , L-> data) ;
L = L-> next;
}
printf ( "\n" ) ;
}
int main ( )
{
LinkList L;
LinkList search;
CreateList1 ( L) ;
PrintList ( L) ;
search = GetElem ( L, 2 ) ;
if ( search != NULL )
{
printf ( "按序号查找成功\n" ) ;
printf ( "%d\n" , search-> data) ;
}
search = LocateElem ( L, 6 ) ;
if ( search != NULL )
{
printf ( "按值查找成功\n" ) ;
printf ( "%d\n" , search-> data) ;
}
ListFrontInsert ( L, 2 , 99 ) ;
PrintList ( L) ;
ListDelete ( L, 4 ) ;
PrintList ( L) ;
}
4. 双链表
4.1 定义
typedef int ElemType;
typedef struct DNode
{
ElemType data;
struct DNode * prior, * next;
} DNode, * DLinkList;
4.2 双链表的插入
4.2.0 插入第i位
bool DListFrontInsert ( DLinkList DL, int i, ElemType e)
{
DLinkList p = GetElem ( DL, i - 1 ) ;
if ( p == NULL )
{
return false ;
}
DLinkList s = ( DLinkList) malloc ( sizeof ( DNode) ) ;
s-> data = e;
s-> next = p-> next;
p-> next-> prior = s;
s-> prior = p;
p-> next = s;
return true ;
}
4.2.1 头插法
DLinkList Dlist_head_insert ( DLinkList& DL)
{
DNode* s; int x;
DL = ( DLinkList) malloc ( sizeof ( DNode) ) ;
DL-> next = NULL ;
DL-> prior = NULL ;
scanf ( "%d" , & x) ;
while ( x != 9999 )
{
s = ( DLinkList) malloc ( sizeof ( DNode) ) ;
s-> data = x;
s-> next = DL-> next;
if ( DL-> next != NULL )
{
DL-> next-> prior = s;
}
s-> prior = DL;
DL-> next = s;
scanf ( "%d\n" , & x) ;
}
}
4.2.2 尾插法
DLinkList DList_tail_insert ( DLinkList& DL)
{
int x;
DL = ( DLinkList) malloc ( sizeof ( DNode) ) ;
DNode* s, * r = DL;
DL-> next = NULL ;
scanf ( "%d" , & x) ;
while ( x != 9999 )
{
s = ( DNode* ) malloc ( sizeof ( DNode) ) ;
s-> data = x;
r-> next = s;
s-> prior = r;
r = s;
scanf ( "%d" , & x) ;
}
r-> next = NULL ;
return DL;
}
4.3 双链表的查找
DNode* GetElem ( DLinkList DL, int i)
{
int j = 1 ;
DNode* p = DL-> next;
if ( i == 0 )
{
return DL;
}
if ( i < 1 )
{
return NULL ;
}
while ( p && j < i)
{
p = p-> next;
j++ ;
}
return p;
}
4.4 双链表的删除
bool DListDelete ( DLinkList DL, int i)
{
DLinkList p = GetElem ( DL, i - 1 ) ;
if ( p == NULL )
{
return false ;
}
DLinkList q;
q = p-> next;
if ( q == NULL )
{
return false ;
}
p-> next = q-> next;
if ( q-> next != NULL )
{
q-> next-> prior = p;
}
free ( q) ;
return true ;
}