大家好啊,今天给大家分享一下对于顺序线性表的相关操作,跟随我的步伐来开始这一篇的学习吧!
如果有知识性错误,欢迎各位指正!!一起加油!!
创作不易,希望大家多多支持哦!
#include <stdio.h>
#include <stdlib.h>
/*此处是顺序线性表数据结构定义*/
typedef int DataType;
struct seqList
{//有3个数据成员
int MAXNUM;//用于记录顺序线性表中能存放的最大元素个数的 整型 MAXNUM
int curNum;//用于存放顺序线性表中数据元素的个数 整型 curNum
DataType *element;//用于存放顺序线性表数据元素的连续空间的起始地址
};
typedef struct seqList *PseqList;
PseqList createNullList_seq(int m) {
//创建一个空的顺序线性表,能存放的最大元素个数为 m
//若m=0,则返回NULL
if (m <= 0) return NULL;
PseqList L = (PseqList)malloc(sizeof(struct seqList));
if (L == NULL) return NULL;
L->MAXNUM = m;
L->curNum = 0;
L->element = (DataType*)malloc(sizeof(DataType) * m);
if (L->element == NULL) {
free(L);
return NULL;
}
return L;
}
int isFullList_seq(PseqList L)
{
//判断顺序线性表是否已满,若已满,返回值为1,否则返回值为0
if (L == NULL) return 0;
return L->curNum == L->MAXNUM;
}
int insertP_seq(PseqList L, int p, int x)
{
// 在线性表L中下标为p的位置插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1
//如果线性表满了, 还需输"list is full"的提示
//如果插入位置非法,需输出提示"position is illegel"
if (L == NULL || p < 0 || p > L->curNum || isFullList_seq(L)) {
if (isFullList_seq(L)) printf("list is full");
if (p < 0 || p > L->curNum) printf("position is illegel");
return 0;
}
for (int i = L->curNum; i > p; --i) {
L->element[i] = L->element[i - 1];
}
L->element[p] = x;
L->curNum++;
return 1;
}
int insertPre_seq(PseqList L, int p, int x)
{
/*在线性表L中下标为p的位置的前面插入数据元素x,若下标p非法或线性表已满无法插入数据,返回0;插入成功返回值为1*/
return insertP_seq(L, p - 1, x);
}
int insertPost_seq(PseqList L, int p, int x)
{
/*在线性表L中下标为p的位置的后面插入数据元素x,若下标p非法或线性表已满无法插入数据,
返回0;插入成功返回值为1*/
return insertP_seq(L, p + 1, x);
}
void printList_seq(PseqList L) {
//逐个输出线性表的元素,相邻的两个数据元素之间以一个空格为分隔符隔开
if (L == NULL) return;
for (int i = 0; i < L->curNum; ++i) {
printf("%d ", L->element[i]);
}
}
int destroyList_seq(PseqList L)
{
//返回值为销毁的线性表中现有数据元素的个数,若待销毁的线性表不存在,则返回0
if (L == NULL) return 0;
int count = L->curNum;
free(L->element);
free(L);
return count;
}
int locate_seq(PseqList L,int x)
{
//在顺序表L中查找给定值x首次出现的位置,若不存在给定值,则返回-1
if (L == NULL) return -1;
for (int i = 0; i < L->curNum; ++i) {
if (L->element[i] == x) return i;
}
return -1;
}
DataType locatePos_seq(PseqList L,int pos)
{
// 在顺序表L中查找指定位置pos处的数据元素,若位置非法,则返回第0个数据元素
if (L == NULL || pos < 0 || pos >= L->curNum) return L->element[0];
return L->element[pos];
}
int deletePos_seq(PseqList L,int pos)
{//在顺序表L中删除与下标pos处的数据元素,若pos非法,则返回-1;否则返回1
if (L == NULL || pos < 0 || pos >= L->curNum) return -1;
for (int i = pos; i < L->curNum - 1; ++i) {
L->element[i] = L->element[i + 1];
}
L->curNum--;
return 1;
}
int delete_seq(PseqList L,int x)
{//在顺序表L中删除与参数x值相同的数据元素,返回删除数据元素的个数
//可以使用之前已完成的操作
int count = 0;
if (L == NULL) return 0;
for (int i = 0; i < L->curNum; ++i) {
if (L->element[i] == x) {
deletePos_seq(L, i);
count++;
i--;
/*由于调用deletePos_seq函数后数据均向前移动一位,所以判断删除掉数据元素的下一位时,该原来的下一位元素已经移动到了删除元素的位置了,所以要将i--,来使下一次仍然判断原删除元素的下标处的新元素。*/
}
}
return count;
}
void replace_seq(PseqList L,int x,int y)
{//将顺序表L中值为x的数据元素替换为y
for (int i = 0; i < L->curNum; i++) {
if (L->element[i] == x) {
L->element[i] = y;
}
}
}
void delDuplicate_seq(PseqList L)
{//移除线性表中的所有重复元素;不使用额外的数组空间,在原地修改输入数组
/*
实现思路
双重循环:
外层循环遍历线性表中的每一个元素,索引为 i。
内层循环从当前元素的下一个元素开始遍历,索引为 j。
查找重复元素:
在内层循环中,检查当前元素 L->element[i] 是否与后续元素 L->element[j] 相等。
如果找到重复元素(即 L->element[i] == L->element[j]),则调用 deletePos_seq(L, j) 删除索引为 j 的元素。
删除元素后,将 k 标记为 1,表示找到了重复元素。
由于删除元素后,后续元素会向前移动,因此需要将 j 减 1,以确保继续检查当前位置的元素。
删除当前元素:
如果 k 为 1(即找到了重复元素),则在外层循环中调用 deletePos_seq(L, i) 删除当前元素 L->element[i]。
删除当前元素后,将 i 减 1,以确保继续检查当前位置的元素。
将 k 重置为 0,以便继续检查下一个元素。
*/
int i, j;
int k=0;
for (i = 0; i < L->curNum - 1; i++) {
for (j = i + 1; j < L->curNum;j++) {
if (L->element[i] == L->element[j]) {
deletePos_seq(L,j);
k=1;
j--;
}
}
if(k==1){
deletePos_seq(L,i);
i--;
k=0;
}
}
}