线性表
单向链表实现:
声明
typedef struct LNode *List;
struct LNode
{
int Data;
List next;
};
求表长
int Length(List PtrL)
{
List p = PtrL;
int j = 0;
while (p)
{
p = p->next;
j++;
}
return j;
}
查找数据
按值查找
List Find(int X, List PtrL)
{
List p = PtrL;
while (p!=NULL && p->Data != X)p = p->next;
return p;
}
按序号查找
List FindKth(int K, List PtrL)
{
List p = PtrL;
int i = 1;
while (p != NULL&&i < K)
{
p = p->next;
i++;
}
if (i == K)return p;
else return NULL;
}
插入数据
- 当插在第一个位置时:创建节点,让该节点直接指向头结点。
- 当插在第i个位置时:创建节点,让该节点指向该位置的后一个节点,再让这个位置的节点指向插入的节点。
List Insert(int X, int i, List PtrL)
{
List p, s;
if (i == 1)
{
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->next = PtrL;
return s;
}
p = FindKth(i-1, PtrL);
if (p == NULL)
{
printf("Error!");
return NULL;
}
else
{
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->next = p->next;
p->Data = s;
return PtrL;
}
}
删除数据
- 当删除头结点时,用一个临时指针指向头结点,将第二个结点当作头结点,再释放原头结点的内存。
- 当删除中间结点时,用一个临时指针指向该中间结点,该位置结点指向下一个结点,再释放要删除的结点的内存。
- p指针指向要删除结点的前一个结点,要注意指向的结点是否为NULL;
List Delete(int i,List PtrL)
{
List p, s;
if (i == 1)
{
s = PtrL;
if (PtrL != NULL)PtrL = PtrL->next;
else return NULL;
free(s);
return PtrL;
}
p = FindKth(i - 1, PtrL);
if (p == NULL)
{
printf("The %d node is not exited!",i-1);
return NULL;
}
else if (p->next == NULL)
{
printf("The %d node is not exited!", i);
return NULL;
}
else
{
s = p->next;
p->next = s->next;
free(s);
return PtrL;
}
}
输出数据
void Print(List PtrL)
{
while (PtrL != NULL)
{
printf("%d ", PtrL->Data);
PtrL = PtrL->next;
}
return;
}
注意
- 自定义的线性表并不一定更要按标准,顾名思义,自定义线性表就是自定义,完全可以自己大胆改变线性表的内容。
循环链表
- 最后一个元素不指向空指针而是指向头节点,形成一个环,这样首尾相接的链表就称为循环链表。
优点
- 查找第一个元素和最后一个元素花费时间降为O(1)。
改变
- 最后一个元素指向头结点。与next原先指向空指针的操作均要改为头结点。
双向循环链表
- 在结点中同时储存两个指针,分别用于指向前驱和后继,同时最后一个指针指向头结点。
优点
- 便于查找前驱后继。
- 查找第一个元素和最后一个元素花费时间降为O(1)。
- 便于反向遍历。
实现代码
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct node Node;
typedef struct node *link;
struct node
{
int element;
link left;
link right;
};
typedef struct dlist *List;
typedef struct dlist Dlist;
typedef struct dlist
{
int n;
link leftEnd, rightEnd;
link header;
};
link NewNode()
{
link L;
L = (link)malloc(sizeof(Node));
return L;
}
List ListInit()
{
node* y;
List L = (List)malloc(sizeof(dlist));
y = NewNode();
y->left = y;
y->right = y;
L->header = y;
L->n = 0;
return L;
}
int ListRetrieve(int k, List L)
{
int i = 1;
link p;
p = L->header->right;
if (k<1 || k>L->n)printf("out of bounds");
while (i < k) { p = p->right; i++; }
return p->element;
}
int ListLocate(int x, List L)
{
int i = 0;
link p;
p = L->header->right;
L->header->element = x;
while (p->element!=x) { p = p->right; i++; }
return ((p == L->header) ? 0 : i);
}
void ListInsert(int x, int k, List L)
{
int i = 0;
link p, y;
p = L->header;
for (i = 1; i < k; i++) { p = p->right; }
y = NewNode();
y->element = x;
y->left = p;
y->right = p->right;
p->right->left = y;
p->right = y;
L->n++;
return;
}
int ListDelete(int k, List L)
{
int x;
link p;
if (k<1 || k>L->n)printf("out of bounds");
p = L->header;
int i = 1;
for (i = 1; i < k; i++)p = p->right;
p->left->right = p->right;
p->right = p->left;
x = p->element;
free(p);
return x;
}
void PrintList(List L)
{
link p;
for (p = L->header->right; p != L->header; p = p->right)
printf("%d ",p->element);
return;
}