/*******线性表*********
* 线性表是最基本、最简单、也是最常用的一种数据结构。
* 线性表(linear list)是数据结构的一种,
* 一个线性表是n个具有相同特性的数据元素的有限序列
* 线性表以下四个特征:
* 1.集合中必存在唯一的一个“第一元素”。
* 2.集合中必存在唯一的一个 “最后元素” 。
* 3.除最后一个元素之外,均有唯一的后继(后件)。
* 4.除第一个元素之外,均有唯一的前驱(前件)。
* ************************/
/*******线性顺序表*********
* 1.特点:逻辑关系相邻的两个元素在物理位置上也是相邻的。
* 优点:可以快速随机存取表中的任一元素。
* 无需为表示表中元素之间的逻辑关系而增加额外的存储空间
* 缺点:在作插入或删除操作时,需要移动大量的元素。
* 当线性表长度变化较大时,难以确定存储空间的容量,造成存储空间的碎片
* 适用:适用于需要大量访问元素的,而增加/删除元素较少的程序
* ************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "phoneNote.h"
#define m_print(list) showSeqList(list,phoneNote_printw)
#define m_search(list,key,value,del) searchSeqList(list,key,value,phoneNote_search,del)
#define m_sort(list,key) sortSeqList(list,key,phoneNote_cmp,phoneNote_swap)
#define m_resver(list) reverSeqList(list,phoneNote_swap)
#define m_modify(list,pos) modifySeqList(list,pos,phoneNote_modify)
#define m_data "seqList.data"
#define SEQLIST_INIT_SIZE 10
#define SEQLIST_INCREMENT 3
#define CAPTION "seqList"
typedef PhoneNote elemType;
typedef void(* elemPrint)(elemType *p);
typedef elemType *(*elemSearch)(elemType *p, const char *key, const char *value);
typedef int (*elemCmp)(elemType *p1,elemType* p2, const char* key);
typedef int (*elemSwap)(elemType *p1,elemType* p2);
typedef int (*elemModify)(elemType *p);
/// @brief 线性顺序表
typedef struct seqList
{
/// @brief 存储空间基地址
elemType *base;
/// @brief 当前存储容量
int capacity;
/// @brief 当前存储大小
int size;
}seqList;
void returnSeqList()
{
char a;
printf("press any key to continue...... ");
/*************************
* scanf()中的%c 不能正常输入的问题
* 在*%c前面加一个空格,将存于缓冲区中的回车符读入
* char a;
* scanf("%c%c",&a,&a);
*************************/
scanf("%c%c",&a,&a);
}
seqList * createSeqList(int size)
{
seqList* rel= (seqList*)calloc(1,sizeof(seqList));
if(rel==NULL){return NULL;}
rel->base = (elemType *)calloc(size, sizeof(elemType));
if(rel->base==NULL) {free(rel);return NULL;}
rel->capacity = size;
return rel;
}
int getLenghtSeqList(seqList* list)
{
if(list==NULL)
{
printf("sequence list is null\n");
return -1;}
printf("sequence list Total:%d\n",list->size);
return list->size ;
}
int incrementSeqList(seqList *list,int size)
{ elemType *newbase=NULL;
newbase=(elemType *)realloc(list->base,(list->capacity+size)*sizeof(elemType));
if(newbase==NULL){
printf("Automatic capacity expansion failed\n"); return 1;
}
list->base=newbase;
list->capacity+=size;
printf("Automatic capacity expansion successfully\n");
return 0;
}
int insertSeqList(seqList *list, elemType *item,int pos)
{
if(list==NULL) { printf("sequence list is null\n"); return -1;}
if(item==NULL) { printf("item is null\n"); return -1;}
if(list->size>=list->capacity)
{
printf("The sequence list space is full\n Automatic capacity expansion\n");
if(0!=incrementSeqList(list,SEQLIST_INCREMENT)){return 1;}
}
if(pos>=list->size){pos=list->size;}
if(pos<0){pos=0;}
for (size_t i = list->size; i >pos; i--)
{
memcpy(list->base+i,list->base+i-1,sizeof(elemType));
}
memcpy(list->base+pos,item,sizeof(elemType));
list->size++;
printf("The sequence list insert successfully\n\n");
return 0;
}
int showSeqList(seqList *list,elemPrint print)
{
if(list==NULL)
{ printf("sequence list is null\n");
return -1;}
if(print==NULL)
{ printf("print function is null\n");
return -2;}
printf("\n-----Show sequence list ------- --------\n");
for (size_t i = 0; i < list->size; i++)
{ print((list->base+i));}
printf("----------- Total: %d --------------------\n\n",list->size);
return 0;
}
int saveSeqList(seqList *list, const char *file)
{
FILE* fp = fopen(file, "wb");
if(list==NULL)
{
printf("sequence list is null\n");
return -1;
}
if(fp==NULL)
{
printf("Failed to open file\n");
return -2;
}
fwrite(list->base,sizeof(elemType),list->size,fp);
fclose(fp);
return 0;
}
int loadSeqList(seqList *list, const char *file)
{
FILE* fp = fopen(file, "rb");
elemType* item=NULL;
if(list==NULL)
{ printf("sequence list is null\n");
return -1;}
if(fp==NULL){
printf("Failed to open file\n");
return -2;
}
item=phoneNote_creat();
if(item==NULL){
printf("Failed to Create empty elemType\n");
return -3;}
while(fread(item,sizeof(elemType),1,fp))
{
insertSeqList(list,item,list->size);
}
fclose(fp);
}
elemType *deleteSeqList(seqList *list, int pos)
{
elemType *rel =(elemType*)calloc(1,sizeof(elemType));
if(list==NULL){ printf("sequence list is null\n");return NULL;}
if(rel==NULL){printf("elemType create is null\n");return rel;}
if(pos>=list->size){pos=list->size-1;}
if(pos<0){pos=0;}
memcpy(rel,list->base+pos,sizeof(elemType));
for (int i = pos; i <list->size-1; i++)
{
memcpy(list->base+i,list->base+i+1,sizeof(elemType));
}
list->size--;
return rel;
}
seqList* searchSeqList(seqList* list,const char* key,const char* value,elemSearch msearch,int del)
{
seqList *rel=createSeqList(SEQLIST_INIT_SIZE);
for (int i = 0; i < list->size; ++i)
{ if(msearch(list->base+i,key,value)!=NULL)
{
insertSeqList(rel,list->base+i,rel->size);
if(del==1){deleteSeqList(list,i); i=i-1;}
}
}
return rel;
}
int clearSeqList(seqList *list)
{
list->size=0;
return 0;
}
int destroySeqList(seqList **list)
{
free((**list).base);
(**list).capacity=0;
(**list).size=0;
(**list).base=NULL;
free(*list);
*list=NULL;
return 0;
}
int sortSeqList(seqList* list ,const char* key, elemCmp cmp,elemSwap swap)
{
/* 冒泡排序 */
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
for (int i=0; i<list->size-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
for (int j=0; j<list->size-1-i; j++) /* 内循环为每趟比较的次数,第i趟比较len-i次 */
{ if (cmp(list->base+j,list->base+j+1,key)>0)/* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
swap(list->base+j,list->base+j+1);
}
return 0;
}
int reverSeqList(seqList* list,elemSwap swap)
{
if(list->size<1) return 0;
for (int i = 0; i < list->size/2 ; i++)
{ swap(list->base+i,list->base+list->size-i-1); }
return 0;
}
seqList* mergeSeqList(seqList *la,seqList *lb)
{
if(la->size<1 || lb->size <1) return NULL;
seqList *rel =NULL;int total=0;
if((rel=createSeqList(la->size+lb->size))==NULL){printf("Sequence table creation failed\n");return NULL;}
for (int i = 0; i < la->size; i++){ insertSeqList(rel,la->base+i,rel->size); }
for (int i = 0; i < lb->size; i++){ insertSeqList(rel,lb->base+i,rel->size); }
return rel;
}
int modifySeqList(seqList *list, int pos, elemModify modify)
{
if(list==NULL || list->size< 1){printf("sequence list is null\n");return -1;}
if(pos<0 || pos>list->size){printf("Position out of range\n"); return-2;}
return modify(list->base+pos);
}
int reduceSeqList(seqList *list, int min)
{ elemType *newbase=NULL;
if(list->size<1){return -1;};
newbase=(elemType *)calloc(list->size,sizeof(elemType));
if(newbase==NULL){return -2;}
for (size_t i = 0; i < list->size; i++)
{
memcpy(newbase+i,list->base+i,sizeof(elemType));
}
free(list->base);
list->base=newbase;
list->capacity=list->size;
return 0;
}
int main(int argc, char const **argv)
{
seqList* list=NULL;
seqList* newList=NULL;
elemType *item =NULL;
list=createSeqList(SEQLIST_INIT_SIZE);
int select = 1;
int pos=-1;
int rel=0;
char cmd[100];
char key[100];
char value[100];
while (select)
{
/* code */
printf("\n******\t%s\t******************\n",CAPTION);
printf("* [1] insert_pos [2] delete_pos *\n");
printf("* [3] show_list [4] search *\n");
printf("* [5] sort [6] rever *\n");
printf("* [7] clear [8] merge *\n");
printf("* [9] reduce [10] delete_val *\n");
printf("* [11] load [12] save *\n");
printf("* [13] modify *\n");
printf("* [0] quit *\n");
printf("************************************\n");
printf("\e[1;32m %s please Enter :>\e[0m",CAPTION);
scanf("%d", &select);
switch (select)
{
case 0: //quit
printf("\e[1;31m SeqList goodbye!\n\e[0m");
return 0;
case 1: //insert_pos
pos=list->size;
printf("Please enter the insertion position [%d] ",pos);
/*****************************
* 只需按Enter键即可使用scanf接受默认值
* char cmd[100];
* scanf("%c",cmd);
* scanf("%[^\n]",cmd);
* ***************************/
scanf("%c",cmd); scanf("%[^\n]",cmd);
if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}
if((item=phoneNote_scanf())==NULL)
{ printf("insert failed,Element is empty\n");break; }
if(insertSeqList(list,item,pos)==0) {m_print(list);}
break;
case 2: //delete_pos
pos=list->size-1;
printf("Please enter the delete position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}
if(NULL!=deleteSeqList(list,pos)) { m_print(list); }
break;
case 3: //show_list
m_print(list);
break;
case 4: //search
printf("Please enter the search key ");scanf("%s",key);
printf("Please enter the search value ");scanf("%s",value);
m_print(m_search(list,key,value,0));
break;
case 5: //sort
printf("Please enter the sort key [name] ");scanf("%c",key); scanf("%[^\n]",key);
if(key[0]<0x30)
strncpy(key,"name",strlen("name")+1);
m_sort(list,key);
m_print(list);
break;
case 6: //resver
m_resver(list);
m_print(list);
break;
case 7: //clear
clearSeqList(list);
m_print(list);
break;
case 8: //merge
list=mergeSeqList(list,list);
m_print(list);
break;
case 9: //reduce
reduceSeqList(list,1);
m_print(list);
break;
case 10: //delete_val
printf("Please enter the delete key ");scanf("%s",key);
printf("Please enter the delete value ");scanf("%s",value);
list=m_search(list,key,value,1);
m_print(list);
break;
case 11: //load
loadSeqList(list,m_data);
printf("\e[1;31m load successful \n\e[0m");
m_print(list);
break;
case 12: //save
saveSeqList(list,m_data);
printf("\e[1;31m save successful \n\e[0m");
break;
case 13: //modify
pos=list->size-1;
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}
m_modify(list,pos);
m_print(list);
break;
default: //please re-enter
printf("\033[32m Wrong selection, please re-enter \033[0m\n");
break;
}
returnSeqList();
}
destroySeqList(&list);
return 0;
}
线性顺序表
最新推荐文章于 2024-07-25 15:31:50 发布