顺序表数组实现
基本操作,增删查改
#include <iostream>
#include<vector>
#define MAXSIZE 100
#define ERROR -1
using namespace std;
typedef struct LNode* List;
typedef int Position;//这是给LNode型指针,一个别名 List
struct LNode {
int data[MAXSIZE];
Position Last;//position为int类型
} ;
/* 初始化列表 */
List MakeEmpty() {//初始化列表操作
List L;//其含义为struct LNode* L,是定义一个LNode类型的
L = (List)malloc(sizeof( struct LNode));
L->Last = -1;
cout << "sqlist已建立" << endl;
return L;
}
/* 查找元素*/
Position Find(List L, int X) {
Position i = 0;
while (i <= L->Last && L->data[i] != X) {
//当前位置小于顺序表长度,
//且L所指向元素不是要查找元素X,位置i增加1
i++;
}
if (i > L->Last) {
return ERROR;
}
else {
return i;
}
}
/*插入元素*/
bool Insert(List L, int X, Position P) {
//在位置P插入一个元素,本质就是在L->data[P]写入
Position i;
//先判断表是否已满
if (L->Last==MAXSIZE-1) {
cout << "表空间已满" << endl;
return false;
}
//再检查所插入位置是否在表空间范围内
if (P<0 || P>L->Last + 1) {//该表为顺序表,那么所有插入元素均需在0-Last+1之间
cout << "插入位置不合法" << endl;
return false;
}
//若以上两条件均满足,则开始插入
for (i = L->Last; i >= P; i--) {
//先将位置P后 的元素向后移动,为位置P腾出空间
L->data[i + 1] = L->data[i];
}
//此时L->data[p]可以覆盖
L->data[P] = X;
L->Last++;//表长增加1
return true;
}
/*删除元素*/
bool Delete(List L,Position P) {
Position i;
if (P<0 || P>L->Last) {//位置p不在表中
cout << "该位置不在表中" << endl;
return false;
}
for (i = P + 1; i <= L->Last; i++) {
L->data[i-1] = L->data[i];//此处写法略复杂
}
L->Last--;
return true;
}
int main() {
List L=MakeEmpty();
Insert(L, 0, 0);
Insert(L, 1, 1);
Insert(L, 2, 2);
Insert(L, 3, 3);
Insert(L, 4, 4);
cout << Find(L, 2) << endl;
Delete(L, 3);
return 0;
}
顺序表的链表实现
该部分有些混乱,主要原因是在于链表有无头节点和节点从0开始计算还是从1开始计算.
#include <iostream>
#include<vector>
using namespace std;
typedef struct LNode* PtrToLNode;
typedef PtrToLNode List;
typedef PtrToLNode Position ;
/*这里的PtrToLNode事实上是一个LNode*型的指针
因此后边的List和Position也是一个LNode*的指针
*/
struct LNode {
int Data;//元素
PtrToLNode Next;//指向下一个的指针
};
/*按值查找*/
#define ERROR NULL
Position Find(List L, int X) {
Position p = L;//p指向List的头节点
while (p&&p->Data!=X)//当P非空且P.data!=X时
{
p = p->Next;
}
/*
当p=null或者p->data=x时退出while循环,此时如果未找到X
则P=NULL ,如果找到了,则P本身指向的就是X的地址
*/
if (p) {
return p;
}
else {
return ERROR;
}
}
/*按序号查找,查找表中第K个元素*/
Position FindKth(List L, int K) {
Position p = L;//p指向头节点
int i = 1;
while (p != NULL && i < K) {
p = p->Next;
i++;
}
if (i == K) {
return p;
}
else {
return NULL;
}
}
/*带头结点*/
/*插入元素*/
bool Insert(List L, int X ,Position P) {
Position tmp, pre;
/*查找P的前一个结点*/
for (pre = L; pre && pre->Next != P; pre = pre->Next);
if (pre ==NULL) {
cout << "插入位置参数错误" << endl;
return false;
}
else {
/*为新节点申请内存空间*/
tmp = (List)malloc(sizeof(struct LNode));
tmp->Data = X;
tmp->Next = P;//将tmp后继指向P
pre->Next = tmp;//将原来p 的前驱指向tmp
return true;
}
}
/*插入元素,在链表的某个位置*/
/*无头结点*/
bool Insert_Kth(List L, int X, int K) {
Position tmp, pre;
if (K== 1) {//插在链表第一个位置,由于不存在头节点
tmp = (List)malloc(sizeof(struct LNode));
tmp->Data = X;
tmp->Next = L->Next;
L->Next = tmp;
return true;
}
pre = FindKth(L, K);
if (pre == NULL) {
cout << "参数K错误" << endl;
return false;
}
else {
tmp = (List)malloc(sizeof(struct LNode));
tmp->Data = X;
tmp->Next = pre->Next;
pre->Next = tmp;
return true;
}
}
/*带头结点删除*/
bool Delete(List L, Position P) {
Position tmp, pre;
for (pre = L; pre && pre->Next != P; pre = pre->Next);
if (pre == NULL || P == NULL) {
/*这里出现两种情况,当P!=NULL但是不在表范围内时,pre==NULL;
当P==NULL时,pre遍历到最后一个节点,此时pre->next=NULL==NULL,
这两种情况只要出现一种即意味着插入删除无法进行.
*/
cout << "删除位置参数错误" << endl;
return false;
}
else {
/*进行到这一步则意味着参数合法*/
pre->Next = P->Next;
free(P);
return true;
}
}
/*按序号删除*/
bool Delete_Kth(List L, int K) {
Position pre,tmp;
if (K == 1) {
tmp = L;
if (L != NULL) {
L = L->Next;
}
else {//L为空链表
return true;
}
free(tmp);
}
pre = FindKth(L, K-1);//查找的是第K个节点的前驱,即第k-1个节点
if (pre == NULL) {
cout << "节点K不存在" << endl;
return false;
}
else if (pre->Next == NULL) {
//这种情况下链表只有k-1个节点
return false;
}
else {//这种情况下K存在
tmp = pre->Next;
pre->Next = tmp->Next;
free(tmp);
return true;
}
}
/*尾插法建立链表-有头节点*/
void InitList_R(List& L, int a[], int n) {
Position pre, tmp;//pre指向的是当前链表的终端节点,tmp为插入元素申请的临时节点
L = (List)malloc(sizeof(struct LNode));
L->Data = n;//头节点首元素存表长
L->Next = NULL;
pre = L;
for (int i = 0; i < n;i++) {
tmp = (List)malloc(sizeof(struct LNode));
tmp->Data = a[i];
pre->Next = tmp;//将当前链表最后节点指向新申请的节点tmp
pre = pre->Next;//将pre指向最后一个节点
}
pre->Next = NULL;
}
/*头插法建立链表*/
void InitList_L(List& L, int a[], int n) {
Position tmp;
L = (List)malloc(sizeof(struct LNode));
L->Data = n;
L->Next = NULL;
for (int i = 0; i < n;i++) {
tmp = (List)malloc(sizeof(struct LNode));
tmp->Data = a[i];
tmp->Next = L->Next;
L->Next = tmp;
}
}
void showList(List L) {//针对有头节点的链表
Position pre;
pre = L->Next;
while (pre != NULL) {
cout << pre->Data << endl;
pre = pre->Next;
}
}
int main() {
List L;
L = (List)malloc(sizeof(struct LNode));
Insert_Kth(L, 1, 1);
Insert_Kth(L, 2, 2);
Insert_Kth(L, 3, 3);
Insert_Kth(L, 4, 4);
Insert_Kth(L, 5, 3);
Delete_Kth(L, 3);//插入删除是从头节点开始算的第K个元素,且从1开始
return 0;
}
两种合并有序链表
递增
/*有序链表合并算法*/
void Merge(List L1, List L2, List& L3) {
Position p = L1->Next;//p指向L1的第一个有数据节点
Position q = L2->Next;//q指向L2的第一个有数据节点
Position r = L3;//r指向L3的头节点
while (p != NULL && q != NULL) {//当L1与L2均非空,即两个链表均没有插完的时候
if (p->Data <= q->Data) {
r->Next = p; p = p->Next;//此句将L3指向L1和L2中较小的节点
r = r->Next;//此时r->Next==NULL
}
else {
r->Next = q; q = q->Next;
r = r->Next;
}
}
if (p != NULL) {//当L2插完而L1还没有插完时,将L1当前节点直接指向L1剩余节点即可.
r->Next = p;
}
if (q != NULL) {
r->Next = q;
}
递减
void Merge_Low(List L1, List L2, List& L3) {
Position p, q;
p = L1->Next;//p,q分别指向L1,L2的第一个节点
q = L2->Next;
L3->Next = NULL;//在外边要建一个包含头节点的链表L3
Position tmp;//tmp用来指向L3的端
while (p != NULL && q != NULL) {
//递减链表与递增链表的不同之处就在于它只是将尾插法改为了头插法
if (p->Data <= q->Data) {
tmp = p;//将tmp指为我们要插入的节点
p = p->Next;//将p指向下一个节点
tmp->Next = L3->Next;
L3->Next = tmp;
}
else {
tmp = q;
q = q->Next;
tmp->Next = L3->Next;
L3->Next = tmp;
}
}
//此时L1 L2中有一个链表已经插完
while (p != NULL) {
tmp = p;//将tmp指为我们要插入的节点
p = p->Next;//将p指向下一个节点
tmp->Next = L3->Next;
L3->Next = tmp;
}
while (q != NULL) {
tmp = q;
q = q->Next;
tmp->Next = L3->Next;
L3->Next = tmp;
}
}
网友评论