/*******线性表*********
* 线性表是最基本、最简单、也是最常用的一种数据结构。
* 线性表(linear list)是数据结构的一种,
* 一个线性表是n个具有相同特性的数据元素的有限序列
* 线性表以下四个特征:
* 1.集合中必存在唯一的一个“第一元素”。
* 2.集合中必存在唯一的一个 “最后元素” 。
* 3.除最后一个元素之外,均有唯一的后继(后件)。
* 4.除第一个元素之外,均有唯一的前驱(前件)。
* ************************/
/*******线性链表(单链表)*********
* 描述:结点 =数据域 + 指针域
用一组地址任意的存储单元存放线性表中的数据元素,
逻辑上相邻的元素在物理上不要求也相邻,不能随机存取
* 优点:动态数据结构、易于插入和删除、内存利用率高
* 缺点:遍历困难,不易于查询,反向遍历困难
* 适用:适用于需要频繁进行增加/删除元素,而查找元素较少的程序。
* ************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "phoneNote.h"
#define MAX_SIZE 20
typedef PhoneNote elemType;
/// @brief 线性链表
typedef struct listNode{
/// @brief 数据
elemType data;
/// @brief 后继
struct listNode *next;
}listNode,*linkList;
#define m_data "linkList.data"
#define BUFF_SZIE 100
#define CAPTION "linkList"
#define m_print(list) showlinkList(list,phoneNote_printw)
#define m_load(list) loadlinkList(list,m_data,phoneNote_creat)
#define m_save(list) savelinkList(list,m_data)
#define m_search(list,key,value,del) searchlinList(list,key,value,phoneNote_search,del)
#define m_insert(list,item,pos) insertlinkList(list,item,pos)
#define m_delete(list,pos) deletelinkList(list,pos)
#define m_clear(list) clearlinkList(list)
#define m_destroy(list) destroylinkList(list)
#define m_lenght(list) getLenghtlinkList(list)
#define m_modify(list,pos) modifylinkList(list,pos,phoneNote_modify)
#define m_merge(la,lb) mergelinkList(la,lb)
#define m_sort(list,key,desc) sortlinkList(list,key,phoneNote_cmp,desc)
#define m_resver(list) resverlinkList(list)
#define m_inputelem() phoneNote_scanf()
linkList createlinkList() {return (linkList)calloc(1,sizeof(listNode));}
int getLenghtlinkList(linkList list){
int i=0;
if(list==NULL) return i;
while(list->next) {i++;list=list->next;}
return i;
}
int insertlinkList(linkList list, elemType *item, int pos)
{
int j=0;
linkList cursor=list;
linkList newList=NULL;
if(!cursor || !item)return -1;
while(cursor && j<pos)
{cursor=cursor->next,j++;}
if(!cursor || j>pos) return -2;
if(!(newList=createlinkList()))return -3;
memcpy(&(newList->data),item,sizeof(elemType));
newList->next=cursor->next;
cursor->next=newList;
return 0;
}
int deletelinkList(linkList list, int pos)
{
int j=0;
linkList cursor=list;
linkList tmp=NULL;
while(cursor->next && j<pos){cursor=cursor->next;j++;}
if(!cursor || j>pos)return -1;
tmp=cursor->next;
if(cursor->next->next)
{cursor->next=cursor->next->next;}
else{cursor->next=NULL;}
free(tmp);
return 0;
}
int modifylinkList(linkList list, int pos, int (*elemModify)(elemType *p))
{ int j=0;
linkList cursor=list;
linkList newList=NULL;
while(cursor->next && j<pos+1)
{cursor=cursor->next;j++;}
if(!cursor || j>pos+1)return -1;
return elemModify(&(cursor->data));
}
linkList searchlinList(linkList list, const char *key, const char *value, elemType *(*elemSearch)(elemType *p, const char *key, const char *value), int del)
{
int j=0;
linkList rel=createlinkList();
linkList cursor=list;
while(cursor && cursor->next)
{
cursor=cursor->next;
if(elemSearch(&(cursor->data),key,value))
{
insertlinkList(rel,&(cursor->data),getLenghtlinkList(rel));
if(del==1){deletelinkList(list,j);cursor=list;j=0;continue;}
}
j++;
}
return rel;
}
int showlinkList(linkList list, void (*_print)(elemType *p))
{ linkList cursor=list;
if(cursor==NULL || _print==NULL) return -1;
printf("\n--------- Show list ------------------\n");
while(cursor)
{_print(&(cursor->data));cursor=cursor->next;}
printf("----------- Total: %d --------------------\n\n",getLenghtlinkList(list));
return 0;
}
int clearlinkList(linkList list)
{
linkList cursor=list;
linkList tmp=NULL;
while(cursor && cursor->next)
{
tmp=cursor->next;
cursor=cursor->next->next ;
free(tmp);}
list->next=NULL;
return 0;
}
int destroylinkList(linkList *list)
{
clearlinkList((*list));
free(*list);
*list=NULL;
return 0;
}
int loadlinkList(linkList list, const char *file, elemType *(*_creatItem)())
{
FILE* fp = fopen(file, "r");
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=_creatItem();
if(item==NULL){
printf("Failed to Create empty elemType\n");
return -3;}
clearlinkList(list);
while(fread(item,sizeof(elemType),1,fp))
{
if(insertlinkList(list,item,getLenghtlinkList(list)))break;
}
fclose(fp);
}
int savelinkList(linkList list, const char *file)
{
linkList cursor=list->next;
FILE* fp = fopen(file, "w");
if(cursor==NULL) {printf("sequence list is null\n");return -1;}
if(fp==NULL){ printf("Failed to open file\n"); return -2; }
while(cursor)
{
fwrite(&(cursor->data),sizeof(elemType),1,fp);
cursor=cursor->next;
}
fclose(fp);
}
linkList mergelinkList(linkList la,linkList lb)
{
linkList cursor=NULL;
linkList rel=createlinkList();
linkList array[]={la,lb};
for (size_t i = 0; i < 2; i++)
{
cursor=array[i];
while(cursor && cursor->next)
{ cursor=cursor->next;
insertlinkList(rel,&(cursor->data),getLenghtlinkList(rel));
}
}
return rel;
}
int sortlinkList(linkList list, const char* key, int (*elemCmp)(elemType *p1,elemType* p2, const char* key),int desc)
{
/*** 插入排序
* 1.从第一个元素开始,该元素可以认为已经被排序;
* 2.取出下一个元素,在已经排序的元素序列中从后向前扫描;
* 3.如果该元素(已排序)大于新元素,将该元素移到下一位置;
* 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
* 5.将新元素插入到该位置后;
* 6.重复步骤2~5。
* 算法的时间复杂度为O(n^2)
* ***/
if(!list && !list->next &&!list->next->next) return 0;
linkList s=list->next;
linkList q=s->next;
linkList p=NULL;
list->next->next=NULL;
while(q)
{
s=q;
q=q->next;
p=list;
switch (desc)
{
case 0:
while(p->next && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
break;
case 1:
while(p->next && elemCmp(&(p->next->data),&(s->data),key)>0){p=p->next;}
break;
default:
while(p->next && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
break;
}
// while(p->next && elemCmp(&(p->next->data),&(s->data),key)<=0){p=p->next;}
// while(p->next && elemCmp(&(p->next->data),&(s->data),key)>0){p=p->next;}
s->next=p->next;p->next=s;
}
return 0;
}
int resverlinkList(linkList list)
{
if(!list && !list->next &&!list->next->next) return 0;
linkList s=0,q=0;
s=list->next;
q=s->next;
list->next->next=NULL;
while(q)
{
s=q;q=q->next;
s->next=list->next;list->next=s;
}
return 0;
}
void printContinue()
{
char a;
printf("press any key to continue...... ");
/*************************
* scanf()中的%c 不能正常输入的问题
* 在*%c前面加一个空格,将存于缓冲区中的回车符读入
* char a;
* scanf("%c%c",&a,&a);
*************************/
scanf("%c%c",&a,&a);
}
int printMenu()
{
int select = 1;
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] resver *\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;32mplease Enter :>\e[0m");
scanf("%d", &select);
return select;
}
int executeCommand(int _cmd)
{
linkList list=createlinkList();
linkList newlist=NULL;
int pos=0,rel=0;
elemType *item =NULL;
while (1)
{
char cmd[100]={0};
char key[100]={0};
char value[100]={0};
switch (printMenu())
{
case 0:
printf("\e[1;31m %s goodbye!\n\e[0m",CAPTION);
m_destroy(&list);return 0 ;/*exit(0)*/;
break;
case 1://insert_pos
pos=m_lenght(list);
printf("Please enter the insertion position [%d] ",pos);
scanf("%c",cmd); scanf("%[^\n]",cmd);
if(cmd[0]>=0x30 && cmd[0]<=0x39 ) {pos=atoi(cmd);}
if((item=m_inputelem())==NULL)
{ printf("insert failed,Element is empty\n");break; }
if(m_insert(list,item,pos)==0) {m_print(list);}
break;
case 2://del_pos
pos=m_lenght(list)-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);}
if(!m_delete(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"));
printf("Please enter the sort key < 0 :abs ,1: desc > [0] ");scanf("%c",cmd); scanf("%[^\n]",cmd);
pos=0;if(cmd[0]>0x30) {pos=atoi(cmd);}
m_sort(list,key,pos);
m_print(list);
break;
case 6: //resver
m_resver(list);
m_print(list);
break;
case 7: //clear
m_clear(list);
m_print(list);
break;
case 8: //merge
m_print(m_merge(list,list));
break;
case 9: //reduce
printf("\033[32m Dynamic space Do not reduce \033[0m\n");
break;
case 10: //delete_val
printf("Please enter the delete key ");scanf("%s",key);
printf("Please enter the delete value ");scanf("%s",value);
m_print(m_search(list,key,value,1));
m_print(list);
break;
case 11: //load
m_load(list);
printf("\e[1;31m load successful \n\e[0m");
m_print(list);
break;
case 12: //save
m_save(list);
printf("\e[1;31m save successful \n\e[0m");
break;
case 13: //modify
pos=m_lenght(list)-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;
}
printContinue();
}
return 0;
}
//int linkListTest(int argc, char const **argv)
int (int argc, char const **argv)
{
return executeCommand(0);
}
线性单链表
最新推荐文章于 2024-09-12 20:36:44 发布