1、顺序表
#include<stdlib.h>
#include<stdio.h>
// 可根据需要自定义数据类型
typedef struct{
char *studentID;
char *studentName;
char *sex;
int age;
char *class;
}DataType;
typedef struct{
int maxSize; //最大元素个数
int listSize; //当前元素个数
int curr; //当前元素的位置
DataType *listArray; //容纳顺序表元素
}AList;
AList create(int size); //创建顺序表
void clear(AList *alist); //清空顺序表的内容
void append(AList *alist, DataType value); //在末尾添加元素
void insert(AList *alist, DataType value); //插入一个元素
DataType delete(AList *alist); //删除并返回当前元素
void moveToStart(AList *alist); //当前元素的位置移到首位
void moveToEnd(AList *alist); //当前元素的位置移到末尾
void next(AList *alist); //当前元素向后移
void prev(AList *alist); //当前元素向前移
void moveToPos(AList *alist, int i); //当前元素移到位置i
DataType getValue(AList alist); //获取当前元素的值
void traverse(AList alist); //遍历
AList create(int size){
AList *alist = (AList *)malloc(sizeof(AList));
alist->maxSize = size;
alist->listSize = 0;
alist->curr = 0;
alist->listArray = (DataType *)malloc(alist->maxSize*sizeof(DataType));
return *alist;
}
void clear(AList *alist){
free(alist->listArray);
alist->listSize = 0;
alist->curr = 0;
alist->listArray = (DataType *)calloc(alist->maxSize, sizeof(DataType));
}
void append(AList *alist, DataType value){
if(alist->listSize >= alist->maxSize){
printf("%s", "list capacity exceeded");
exit(0);
}
alist->listArray[alist->listSize] = value;
alist->listSize++;
}
void insert(AList *alist, DataType value){
if(alist->listSize >= alist->maxSize){
printf("%s", "list capacity exceeded");
exit(0);
}
for(int i = alist->listSize; i >= alist->curr; i--){
alist->listArray[i] = alist->listArray[i-1];
}
alist->listArray[alist->curr] = value;
alist->listSize++;
}
DataType delete(AList *alist){
if(alist->curr < 0 || alist->curr >= alist->listSize){
printf("%s", "no element");
exit(0);
}
DataType res = alist->listArray[alist->curr];
for(int i = alist->curr; i < alist->listSize - 1; i++){
alist->listArray[i] = alist->listArray[i+1];
}
alist->listSize--;
return res;
}
void moveToStart(AList *alist){
alist->curr = 0;
}
void moveToEnd(AList *alist){
alist->curr = alist->listSize;
}
void next(AList *alist){
if(alist->curr < alist->listSize){
alist->curr++;
}
}
void prev(AList *alist){
if(alist->curr > 0){
alist->curr--;
}
}
void moveToPos(AList *alist, int i){
if(i < 0 || i >= alist->listSize){
printf("%s", "index out of range");
exit(0);
}
alist->curr = i;
}
DataType getValue(AList alist){
return alist.listArray[alist.curr];
}
void traverse(AList alist){
for(moveToStart(&alist); alist.curr < alist.listSize; next(&alist)){
printf("%s\t", getValue(alist).studentID);
printf("%s\t", getValue(alist).studentName);
printf("%s\t", getValue(alist).sex);
printf("%d\t", getValue(alist).age);
printf("%s\n", getValue(alist).class);
}
}
测试代码
#include"AList.h"
int main(){
AList alist = create(3);
DataType stud1 = {"20181745", "ycl", "male", 21, "5ban"};
DataType stud2 = {"20181750", "ydx", "male", 23, "5ban"};
DataType stud3 = {"20181736", "wdl", "male", 22, "5ban"};
append(&alist, stud1);
append(&alist, stud2);
append(&alist, stud3);
traverse(alist);
return 0;
}
2、链表
注意事项:
1、当链表为空时,头节点、尾节点、当前节点无处可指,在插入删除操作时,需要增加额外的代码。为此,增加一个空节点。初始时刻,头节点、尾节点、当前节点指向空节点。

2、当前节点实际上指向的是前一个节点(为了方便插入操作)。换句话说,进行插入操作时,在当前节点的后面插入。同理,获取当前节点时,实际上是获取当前节点的后一个节点。

3、在进行插入和删除操作时,注意对尾节点的细节处理。插入操作需要保证尾节点始终在链表末尾,删除操作需要保证尾节点不会无处可指。
#include<stdio.h>
#include<stdlib.h>
typedef struct{
char *studentID;
char *studentName;
char *sex;
int age;
char *class;
}DataType;
typedef struct node{
DataType value;
struct node *next;
}node;
typedef struct{
node *head; // 头节点
node *tail; // 尾节点
node *curr; // 当前节点(为了方便进行插入或删除操作,实际上操作的是当前节点的下一个节点)
int count; // 链表当前节点数(空节点除外)
}LList;
LList create(); // 创建链表
void clear(LList *llist); // 清空链表
void append(LList *llist, DataType value); // 在链表末尾添加节点
void insert(LList *llist, DataType value); // 在当前位置插入节点
DataType delete(LList *llist); // 在当前位置删除节点
void moveToStart(LList *llist); // 移到表头
void moveToEnd(LList *llist); // 移到表位
void moveToPos(LList *llist, int pos); // 移到指定位置(pos从0开始)
void next(LList *llist); // 当前位置向后移
DataType getValue(LList llist); // 获取当前节点的元素
void traverse(LList llist); // 遍历链表
void init(LList *llist){
// 当链表为空时,头节点、尾节点、当前节点无处可指,在插入删除操作时,需要增加额外的代码。
// 为此,增加一个空节点
node *n = (node *)malloc(sizeof(node));
n->next = NULL;
// 头节点,尾节点,当前节点指向空节点
llist->head = n;
llist->curr = n;
llist->tail = n;
llist->count = 0;
}
void removeall(LList *llist){
// 只要链表不为空,不断地从头删除节点
while(llist->head != NULL){
llist->curr = llist->head;
llist->head = llist->head->next;
free(llist->curr);
}
}
LList create(){
LList *llist = (LList *)malloc(sizeof(LList));
init(llist);
return *llist;
}
void clear(LList *llist){
removeall(llist);
init(llist);
}
void append(LList *llist, DataType value){
node *n = (node *)malloc(sizeof(node));
n->value = value;
n->next = NULL;
// 让链表尾节点指向它(注意指针与实际物理内存的联系,不然会产生疑惑)
llist->tail->next = n;
llist->tail = llist->tail->next;
llist->count++;
}
void insert(LList *llist, DataType value){
node *n = (node *)malloc(sizeof(node));
n->value = value;
n->next = llist->curr->next;
llist->curr->next = n;
// 如果当前节点为尾节点,那么尾节点需要指向该节点(尾节点始终应该在链表末尾)
if(llist->curr == llist->tail){
llist->tail = llist->curr->next;
}
llist->count++;
}
DataType delete(LList *llist){
// getValue已经判断了是否为空的情况
DataType value = getValue(*llist);
node *n = llist->curr->next;
// 如果待删除的节点为尾节点,那么尾节点需要指向当前节点(因为尾节点不应该无处可指)
if(llist->curr->next == llist->tail){
llist->tail = llist->curr;
}
llist->curr->next = llist->curr->next->next;
free(n);
llist->count--;
return value;
}
void moveToStart(LList *llist){
llist->curr = llist->head;
}
void moveToEnd(LList *llist){
llist->curr = llist->tail;
}
void moveToPos(LList *llist, int pos){
if(pos < 0 || pos >= llist->count){
printf("position out of range");
exit(0);
}
moveToStart(llist);
int i = 0;
while(i < pos){
llist->curr = llist->curr->next;
i++;
}
}
void next(LList *llist){
if(llist->curr != llist->tail){
llist->curr = llist->curr->next;
}
}
DataType getValue(LList llist){
if(llist.curr->next == NULL){
printf("No value");
exit(0);
}
// 返回的是当前节点的下一个节点的值
return llist.curr->next->value;
}
void traverse(LList llist){
for(moveToStart(&llist); llist.curr != llist.tail; next(&llist)){
printf("%s\t", getValue(llist).studentID);
printf("%s\t", getValue(llist).studentName);
printf("%s\t", getValue(llist).sex);
printf("%d\t", getValue(llist).age);
printf("%s\n", getValue(llist).class);
}
}
测试代码
#include"LList.h"
int main(){
LList llist = create();
DataType stud1 = {"20181745", "ycl", "male", 21, "5ban"};
DataType stud2 = {"20181750", "ydx", "male", 23, "5ban"};
DataType stud3 = {"20181736", "wdl", "male", 22, "5ban"};
append(&llist, stud1);
append(&llist, stud2);
append(&llist, stud3);
traverse(llist);
return 0;
}

529

被折叠的 条评论
为什么被折叠?



