C语言-数据结构-顺序表

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;
}


猜你喜欢

转载自blog.csdn.net/qq_32460819/article/details/81285853