顺序表
走过路过不要错过的啦!
顺序表的6个基本运算
1:顺序表初始化运算的实现
void initialList(seqList *L)
{
//由于所需要的连续储存空间在代码编译时候已经确定,只需要把长度设为0
L->listLen = 0;
}
2:求表长度函数的实现
int listLengt(seqList L){//返回类型为int
return L.listLen;
}
3:按序号求元素的实现
void getElement(seqlist L,int i ,elementType * x){
if(i <1 || i > L.listLen){
//自定义实现报错信息
}else{
*x = L.data[i-1];
}
}
4:查找元素的实现
int listLocate(seqList L,elementType x){
int i ;
for(i = 0 ;i< L.listLen ;i++){
if(L.data[i] = x;
return i + 1;
}
return 0;//表示未查找的元素
}
5:插入算法的实现
int listInsert(serList* L, elementType x, int i) {
int j;
if (L->listLen == MAXLEN) {
return 0;//表示表满,无法插入新的元素
}
else if (i < 1 || i > L->listLen + 1) {
return -1 //表示超出范围
}
else {
for (j = L->listLen; j >= i; j--) {//将将要插入的位置后面的信息单元依次后移一个单元
L->data[j] = L->data[j + 1];
}
L->data[i] = x;
L->listLen++;
return 1//表示成功
}
6:删除算法的实现
int listDelet(seqList *L, int i){
int j;
if (L->listLen == 0) {
return 0;//表示空表
}
else if (i < 1 || i > L->listLen + 1) {
return -1;//表示索引范围越界
}
else {
for (j = i ; j < L->listLen; j++)
{
L->data[j-1] = L->data[j];
}
L->listLen--;
return 1;//表示删除成功
}
}
无序顺序表的交并差
1:交
//求C=A∩B
void interSet(List A, List B, List &C)
{
int i;
for(i=0;i<A.listLen;i++)//遍历A集合
{
if(listLocate(B,A.data[i])!=0){//判断A.data[i]是否在B中出现
listInsert(&C,A.data[i],C.listLen+1);//插入交叉元素
}
}
}
2:并
//求C=A∪B
void mergeSet(List A, List B, List &C)
{
int i;
for(i=0;i<A.listLen;i++) //先把A中元素全部插入到C中
{
listInsert(&C,A.data[i],C.listLen+1);
}
for(i=0;i<B.listLen;i++)//再插入B中除去A中所含的元素
{
if(listLocate(A,B.data[i])==0)
{
listInsert(&C,B.data[i],C.listLen+1);
}
}
}
3:差
//求C=A-B
void differentSet(List A,List B,List &C)
{
int i;
for(i=0;i<A.listLen;i++)
{
if(listLocate(B,A.data[i])==0) //插入A中B所没有的元素
{
listInsert(&C,A.data[i],C.listLen+1);
}
}
}
有序顺序表的两个例子
1:设计算法A= A∩B
void InterSet(List &A, List &B)
{
int i= 0; //为了最后更新交集元素表长度操作一致,初始化为-1i
int a=0, b=0; //A、B表当前元素的数组下标
while(a<A.listLen && b<B.listLen)
{
if(A.data[a]==B.data[b]) //a和b指示的是交集元素
{
if(a!=i)//a元素复制到i+1,否则a位置即目标位置,不需复制元素
{
A.data[i]=A.data[a];
i++;
a++;
b++;
}
else if(A.data[a]<B.data[b]) { //以下为非交集元素处理
a++;
}
else{
b++;
}
}
A.listLen=i; //更新A表长度,使等于交集元素个数
}
2:设计算法A=A-B
void Set (List & A, List & B)
{
int i=0; //指示A中已经处理的最后元素
int a=0, b=0; //初始化A,B位
while( a<A.listLen && b<B.listLen )
{
if(A.data[a]==B.data[b]) //当a,b相同时,a、b同时后移
{
a++;
b++;
}
else if(A.data[a]>B.data[b]){
b++;
} //此时,a指示元素排在b指示的元素后面,移动b。
else
{ //所以a指示元素必在A-B中。//如果(i+1)==a,说明a元素不需迁移位置,直接为A-B中元素
if(i!=a)
{
A.data[i]=A.data[a];
}
i++; //A-B集合最后元素指示后移
a++; //A的指示后移
}
}
//处理B结束,A未结束情况,A中剩下部分元素全部为所差元素
while(a<A.listLen)
{
if(i!=a){
A.data[i]=A.data[a];
}
i++; //A-B集合最后元素指示器后移
a++; //A的指示器后移
}
A.listLen=i + 1; //更新表A的长度
}
链表:
链表基本运算的实现
1:初始化链表运算的实现
void intialList(node * &L)//这里使用引用的方式回传初始化链表
{
L = new node;//申请头结点
L->next = null;//头结点后继指针为null
}
2:求链表长度
int listLength(node *L)
{
int len = 0;//设置计数器
node * p = L->next;//p初始化指向首元素地址
while(p != null)
{
len++;
p = p->next; //p移到下一个结点,继续后续节点的奇数
}
return len;//返回结果
}
3:按序号取元素结点的实现
node * getElement(node *L, int i)
{
//可以在此之前对i进行检查,此处省去
node* p = L->next;//p指向第一个元素地址
int j = 1;//设置计数器
while(p != null && j != i)
{
j++;
p = p->next;
}
return p;
}
4:按值查询元素
node* listLocate(node* L, elementType x)
{
node* p = L->next;//指向首元素地址
while (p != null && p->data != x) {
p = p->next;//p不是目标结点,继续搜索下一个结点
}
return p;
}
5:插入算法的实现
bool listInset(node* L ,int i,elementType x)
{
node * p = L;//p指向头结点
node* S;
int k = 0;//设置计数器
while(k != i - 1 && p != null)
{
p = p->next;//p指向下一个结点
k++;//计数器加一
}
if (p == NULL)
{
return false;//说明插入位置无效
}
else
{
S = new node;
S->data = x;//装入数据
S->next = p->next;//改变逻辑结构
p->next = S;
return true;//返回true表示插入完成
}
}
6:删除算法的实现
bool listDelete(node* L , int i)
{
node* temp;
node* p = L;//指向头结点,之所以不指向首元素是因为可能要删除首元素
int k = 0;//设置计数器
while (k != i && p->next != null)//删除,需要该节点的上一个结点p,因此结点p后继结点必须要存在,p不是尾结点
{
p = p->next;
k++;
}
if (p->next == NUll)
{
return false;
}
else
{
/*
这样不容易释放原先p之后的结点元素地址
temp = p->next->next;
p->next = temp;*/
temp = p->next;
p->next = temp->next;
delete temp;
return true;
}
}
有问题欢迎指正!