前言
本文是学习线性表、链表的记录。包括各种链表的基本操作,遇到题目会继续更新。大部分代码是C++,偶尔C。
一、顺序表的定义与操作
顺序存储的优点:
(1)结点等长可实现随机存取
(2)存储密度高,节省空间
(3)符合物理存储次序
顺序存储的缺点:
(1)插入删除时要移动大量结点
(2)必须静态分配连续空间
1.定义与初始化
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;
}
2.查找
/*查找*/
#define ERROR -1
Position Find(List L,ElementType x){
Position i = 0;
while(i <= L->list &&L->Data[i] != x) i++;
if(i > L->Last) return ERROR;
else return i;
}
3.插入
/*插入*/
bool Insert(List L,ElementType x,Position P){
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--){
/*位置P后元素顺序后移*/
L->Data[i+1] = L->Data[i];
}
L->Last[i] = x;
L->Last++;//指向最后元素
return true;
}
3.删除
/*删除*/
bool Delete(List L,Position P){
Position i;
if(P < 0||P > L->Last){
printf("位置%d不存在元素",P);
return false;
}
for(i = P+1;i <= L->Last:i++){
/*如果从P开始,最后的i+1会出链表尾*/
L->Data[i-1] = L->Data[i];
}
L->Last--;
return true;
}
二、单链表的定义与操作
链式存储的优点:
(1)插入删除比较灵活,不需要大量移动结点
(2)动态分配空间比较灵活,不需要提前申请最大连续空间
链式存储的缺点:
(1)增加指针空间开销
(2)检索必须沿链进行,不能随机存取
1.定义
typedef struct LNode *pLink;
struct LNode{
ElementType Data;
Link Next;
};
typedef pLink Position;
typedef pLink List;
1.整表创建
(1)头插法
/*单链表的创建(头插法)*/
void CreateListHead(List L,int n){
Position pre;
int i;
srand(time(0));//生成随机数做data
L = (List)malloc(sizeof(struct LNode));
L->next = NULL;
for(i = 0;i < n;++i){
pre =(Position)malloc(sizeof(struct LNode));
pre->Data = rand()%100+1;//随机生成100以内的数字
pre->Next = L->Next;
L->Next = pre; //插入到表头
}
}
(2)尾插法
/*单链表的创建(尾插法)*/
bool CreateListTail(List L,int n){
Position tmp,tail;
int i;
srand(time(0));
L = (List)malloc(sizeof(struct LNode));
tail = L;
for(i = 0;i < n;++i){
tmp = (Position)malloc(sizeof(struct LNode));
tmp->Data = rand()%100+1;
tail->Next = tmp;
tail = tmp;
}
tail->Next = NULL;
return true;
}
2.查找
/*查找*/
#define ERROR NULL
Position Find(List L,ElementType x){
Position p = L; //p指向第一结点
while(p && p->Data != x)
p = p->Next;
return p;
/*如果到最后退出循环,下一个也是NULL,同ERROR*/
}
3.插入
/*带头结点的插入*/
bool Insert(List L,ElementType x,Position P){
Postion tmp,pre;
for(pre = L;pre && pre->next != P;pre = pre->next)
if(pre == NULL){
/*P不在中*/
cout<<"插入位置参数错误"<<endl;
return false;
}
else{
/*找到P的前一个结点*/
tmp = (Position)malloc(sizeof(struct Lnode));
tmp->data = x;
tmp->Next = P;
pre->Next = tmp;
return true;
}
}
4.删除
/*带头结点的删除*/
bool Delete(List L,Position P){
Position pre;
for(pre = L;pre && pre->Next != P;pre = pre->Next)
if(pre == NULL || P ==NULL)
cout<<"删除位置参数错误"<<endl;
return false;
else{
pre->Next = P->Next;
free(P);
return true;
}
}
5.整表清空
/*单链表的清空*/
bool ClearList(List L){
Position pre,tmp;
pre = L->Next;
while(pre)
{
tmp = pre->Next;
free(pre);
pre = tmp;
}
L->Next = NULL;
return true;
}
最后
掌握了基础操作后,还需要多练习加深理解。
如以上有问题,请不吝赐教。