C语言 数据结构 相关 顺序表 函数
在网上查了很多关于顺序表的资料,但是都差强人意,大部分都是由C++编写,且编写顺序和函数都不够详细
由于本人对C语言掌握的还可以,所以一下程序全部使用C语言进行编写, 使用编译工具是Dev C++,文件是.c文件

有什么相关细节问题可以留言区留言,感谢你的观看.

#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"

#define NewLine printf("\n")
#define MAX_SIZE 50

//所有返回-1都是错误

typedef struct{
int data[MAX_SIZE];
int length;
}List;

List *CreateList(void); //开辟空间
void ListDisplay(List *L); //显示顺序表
int ListInsert(List *L, int k, int e); //在位置k 插入e
int ListDel(List *L, int k, int *e); //在位置k 删除数值保存到e
int ListFind_e(List *L, int e); //找元素e的位置
int ListDel_Min_From_FinElem(List *L); //删除最小值,将值返回,将最后一个元素替换到原来位置
int ListReverse(List *L); //反置
void Swap(int *a, int *b); //交换两个数值
int ListDel_All_e(List *L, int e); //删除所有与e
int ListDel_FromSToT(List *L, int s, int t); //删除给定的位置范围的所有值;
int ListDel_s_t(List *L, int s, int t); //删除顺序表中顺序给定值s,t之间的数据 (s<t)
int ListDel_s_t_disorder(List *L, int s, int t); //删除顺序表中乱序的在st之间的所有值
int ListDel_Repeat(List *L); // 删除有序 顺序表中重复数据
List* ListMerge(List *L1, List *L2); //链接两个顺序表,返回链接好的顺序表


int main()
{
int i,e;
int a[20]={1,2,3,4,4,5,5,5,5,5,6,6,7,8,9,10,11,12,15,15};
List *L, *L2;


L = CreateList(); //开始创建
L2 = CreateList(); //创建第二个顺序表

for(i=0; i<20; i++) //赋值
{
L->data[i] = i;
L->length++;
}
ListDisplay(L);

printf("\n在第2位置插入66");
ListInsert(L,2,66); //在第2位置插入66
ListDisplay(L);

printf("\n删除第二个位置\n");
ListDel(L,2,&e); //第二个位置删除,删除的数据保存到e中
printf("del = %d ",e);
ListDisplay(L);

printf("\n数据6存在的是位置%d\n\n",ListFind_e(L,6)); //显示数据位置

printf("已删除最小数据%d,且有最后一位数据做填补",ListDel_Min_From_FinElem(L));
ListDisplay(L);

printf("\n 转置所有数据 ");
ListReverse(L); //顺序表转置
ListDisplay(L);
ListReverse(L); //顺序表转置
ListDisplay(L);

printf("\n 删除所有5数据 ");
ListDel_All_e(L,5); //删除所有5
ListDisplay(L);

printf("\n 删除位置5到8的值 ");
ListDel_FromSToT(L,5,8);
ListDisplay(L);

printf("\n 删除10,14 之间的数据 ");
ListDel_s_t(L,10,14);
ListDisplay(L);


printf("\n 删除(3 <= x <= 11)之间的数据 ");
ListDel_s_t_disorder(L,3,11);
ListDisplay(L);

//重新赋值
printf("\n新赋值\n");
L->length=0;
for(i=0; i<20; i++)
{
L->data[i] = a[i];
L->length++;
}
ListDisplay(L);

printf("\n删除重复数据 ");
ListDel_Repeat(L);
ListDisplay(L);

//给第二个顺序表赋值
printf("\n第二个顺序表赋值");
for(i=0; i<20; i++)
{
L2->data[i] = i;
L2->length++;
}
ListDisplay(L2);


printf("\n链接两个顺序表 ");
L2 = ListMerge(L2,L);
ListDisplay(L2);



printf("\n Hello word!!\n");
return 0;
}


/*创建*/
List *CreateList(void)
{
List *L;
L = malloc(sizeof(List)); //申请空间
L->length = 0; //长度从1开始
return L; //返回指针地址
}

/* 显示顺序表 */
void ListDisplay(List *L)
{
int i;
NewLine;
for(i=0; i < L->length; i++) {printf("%d, ",L->data[i]);}
NewLine;
}

/* 在L中第k位插入e */
int ListInsert(List *L, int k, int e)
{
int j;
if(L->length >= MAX_SIZE)
{
printf("FULL\n");return;
}
if((k<1) || (k > (L->length+1))) return -1;//超出范围
for(j=L->length; j>=k; j--)
{
L->data[j] = L->data[j-1]; //向前移位
}
L->data[k-1] = e;
L->length++;
return 1;
}

/* 删除L中第k个位置,并删除的数据保存到e中 */
int ListDel(List *L, int k, int *e)
{
int i;
if((k<1) || (k > (L->length))) return -1;//超出范围
*e=L->data[k-1];
for(i=k; i<L->length; i++)
{
L->data[i-1]=L->data[i];
}
L->length--;
return 1;
}

/* 在L中查找数值e 在第几个位置 */
int ListFind_e(List *L, int e)
{
int i=0;
while( (e != L->data[i]) && (i != L->length-1) )
{
i++;
}
if(i>=L->length) return -1;
return i+1;
}

/*
王道 数据结构 P18.1
从顺序表中删除具有最小值的元素,假设唯一,
并由函数返回被删除的值, 且被删除的位置由最后
一个元素填补,顺序表为空则显示出错信息 */

int ListDel_Min_From_FinElem(List *L)
{
int del;
int i=1,pos=0;
if (L->length==0)
{
printf("NULL!\n");
return -1;
}
del=L->data[0];
for(i=1; i<L->length; i++)
{
if(del > L->data[i])
{
del=L->data[i];
pos=i;
}
}
L->data[pos] = L->data[ L->length ];
L->length--;
return del;
}

/*
空间复杂度为O(1) 将顺序表中的数据逆置

分析: 将前后两半对换,只需要找到一个中间变量,或者使用逻辑运算进行转换

*/

int ListReverse(List *L)
{
int i;
if(L->length == 0)
{
printf("NULL!\n");return -1;
}
for(i=0; i<L->length/2; i++) //1 2 3 4 5 6
{
L->data[i] = L->data[i] ^ L->data[L->length-1-i];
L->data[L->length-1-i] = L->data[i] ^ L->data[L->length-1-i];
L->data[i] = L->data[i] ^ L->data[L->length-1-i];
}
return 1;
}

/* 实现不使用中间变量,交换两个参数的数值 */
void Swap(int *a, int *b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;

// *a = *a + *b;
// *b = *a - *b;
// *a = *a - *b;
//
// *a = *a * *b;
// *b = *a / *b;
// *a = *a / *b;
}

/*
编写时间复杂度O(n) 空间复杂度O(1)
将顺序表中的所有元素e删除
*/
int ListDel_All_e(List *L, int e)
{
int i,timer=0;
for(i=0; i<L->length; i++)
{
if(L->data[i] != e)
{
L->data[timer] = L->data[i];
timer++;
}
}
L->length = timer;
return i;
}

/*
删除给定的位置s,t之间的所有值,包含s&t
如果s,t不合理,或者顺序表为空,打印错误
*/
int ListDel_FromSToT(List *L, int s, int t)
{
int i;
if(L->length == 0)
{
printf("NULL!\n");
return -1;
}
if(s<1 || s > L->length || t<1 || t>L->length || s>=t)
{
printf("/n input ERROR!\n");
return -1;
}

for(t; t<L->length; t++) //3,5
{
L->data[s-1] = L->data[t-1];
s++;
}
L->length -= (t-s+1);
}

/*
删除有序顺序表中 数据全部s 到 t范围内的数据(包括数据s&t)
如 1 2 3 4 5 6 7 8 9 10 删除2 - 4
如果s,t不合理,或者顺序表为空,打印错误
*/
int ListDel_s_t(List *L, int s, int t)
{
int i=0,j=0;
if(L->length == 0)
{
printf("NULL!\n");
return -1;
}
if(s >= t)
{
printf("/n input ERROR!\n");
return -1;
}
while((L->data[i] != s) && (i < L->length) ) //寻找第一个等于s的值
{
i++;
}
j=i;
while ( ((L->data[j]) <= t) && (j < L->length) ) //寻找第一个小于t的值
{
j++;
}
for(j; j<L->length; j++)
{
L->data[i] = L->data[j];
i++;
}
L->length = i++; //当j==L->length for循环并没有执行,所以需要加1
return 1;
}

/*
删除顺序表中所有在s t之间的所有数据,包括s,t
*/
int ListDel_s_t_disorder(List *L, int s, int t)
{
int i,timer;
if(L->length == 0)
{
printf("NULL!\n");
return -1;
}
if(s >= t)
{
printf("/n input ERROR!\n");
return -1;
}
timer=0;
for(i=0; i<L->length; i++)
{
if(L->data[i] <s || L->data[i] >t)
{
L->data[timer] = L->data[i];
timer++;
}
}
L->length = timer;
return 1;
}

/*
删除 有序 顺序表中重复data,

*/
int ListDel_Repeat(List *L)
{
int i=0,next;
if(L->length == 0)
{
printf("NULL!\n");
return -1;
}

for(next=1; next < L->length; next++)
{
if( L->data[i] != L->data[next] )
{
L->data[++i] = L->data[next];
}
}
L->length = i + 1;
return 1;
}

/*
将两个有序顺序表合成一个有序顺序表
返回顺序表

先比较两个表的最小值,然后放到一个位
在用这个值分别比较两个表的下一个值,哪个值更接近这个值,就是第二个
*/
List* ListMerge(List *L1, List *L2)
{
List *L;
int i,j,k;

if(L1->length + L2->length > MAX_SIZE)
{
printf("FULL!\n");return -1;
}

i=j=k=0;

while(i<L1->length && j<L2->length)
{
if(L1->data[i] <= L2->data[j])
{
L->data[k] = L1->data[i];
i++;
} else
{
L->data[k] = L2->data[j];
j++;
}
k++;
}

printf("\n 000 %d\n",L1->length);
if(i == L1->length) //L1已耗尽,向L中加剩余的j
{
while( j<L2->length )
{
L->data[k] = L2->data[j];
k++;
j++;
}
}else if(j == L2->length) //L2 已耗尽
{
while( i<L1->length )
{
L->data[k] = L1->data[i];
k++;
i++;
}
}
L->length = k;
return L;
}