单链表 实现如下单链表:
文章图片
可以增删改查自定义的Person结构体,用C++,但用C语法写的。
代码
#include
#include
#include
using namespace std;
//懒得用gcc编译,直接在c++里面用c的格式来写
//提示:malloc,free
//注意打印的datatypedef struct LINKNODE
{
//这个数据是扫描还是未知的
void* data;
struct LINKNODE* next;
}LinkNode;
typedef struct LINKLIST
{
LinkNode* head;
int size;
}LinkList;
//先定义一个函数类型,等下放这个名字
//这里只是占个坑,等下还要具体化一个void myPrint(void* data){}
typedef void (PRINTLIST)(void*);
typedef struct PERSON
{
char name[64];
int id;
int age;
}Person;
void myPrint(void* data)
{
//打印函数,和上面的那个typedef呼应
Person* p = (Person*)data;
printf("name: %s,id: %d,age: %d\n",p->name,p->id,p->age);
}LinkList* init()
{
LinkList* list = (LinkList*)malloc(sizeof(LinkList));
//头结点不放数据,内容全置为空
list->head = (LinkNode*)malloc(sizeof(LinkNode));
list->size = 0;
list->head->data = https://www.it610.com/article/NULL;
list->head->next = NULL;
return list;
}void insert(LinkList* list,int pos, void* data)
{
//根据指定位置插入
if(list==NULL || data=https://www.it610.com/article/=NULL)
{
return;
}if(pos<0 && pos>list->size)
{
pos = list->size;
}
//创建新的节点,即要插入的那个
LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));
newNode->data = https://www.it610.com/article/data;
newNode->next = NULL;
//找到要插入的那个节点
LinkNode* pcurrent = list->head;
for(int i = 0;
inext;
}
//新节点插入
newNode->next = pcurrent->next;
pcurrent->next = newNode;
//size++
list->size ++;
}void removeByPos(LinkList* list,int pos)
{
//根据指定位置删除元素
if(pos<0 || pos>list->size)
{
return;
}
//弄一个指针来找那个位置的前一个
LinkNode* pcurrent = list->head;
for(int i = 0;
i【c++ 数据结构之实现单链表增删改查自定义Person对象】next;
}
//要弄个临时存的
LinkNode *temp = pcurrent->next;
pcurrent->next = pcurrent->next->next;
//清除删除节点的数据,避免泄露,这里并没有清除data的数据,不知道为什么老报错
free(temp);
list->size --;
}int getSize(LinkList* list)
{
//返回元素size
return list->size;
}int findElement(LinkList* list,void* data)
{
Person* p = (Person*)data;
LinkNode* temp = list->head->next;
for(int i = 0;
isize;
i++)
{
//打印地址的格式,强行用%d,有正有负
//printf("p:%p,temp->data:%p",p,temp->data);
if(p == temp->data)
{
return i;
}
//注意temp要指向next啊,不然原地踏步
temp = temp->next;
}
return -1;
}void* front(LinkList* list)
{
return list->head->next;
}//打印,需要传入一个回调函数,因为不知道打印的是什么类型的数据
//打印自定义的Person类
void printList(LinkList* list,PRINTLIST print)
{
if(list==NULL)
{
return;
}
LinkNode* pcurrent = list->head->next;
while(pcurrent != NULL)
{
print((Person*)pcurrent->data);
pcurrent = pcurrent->next;
}
}//释放链表空间,注意这里要一个个释放,但又不能直接free了,不然找不到下一个
void freeList(LinkList* list)
{
if(list==NULL)
{
return;
}
LinkNode* temp = list->head;
while(temp!=NULL)
{
//要保存一下下一个节点,不然free了就什么都没了
LinkNode* pnext = temp->next;
free(temp);
temp = pnext;
}
//释放链表
list->size = 0;
free(list);
}void test()
{
LinkList* list = init();
Person p1 = {"a",1,11};
Person p2 = {"b",2,11};
Person p3 = {"c",3,11};
Person p4 = {"d",4,11};
Person p5 = {"d",4,11};
insert(list,0,(void*)&p1);
insert(list,0,(void*)&p2);
insert(list,0,(void*)&p3);
insert(list,0,(void*)&p4);
printList(list,myPrint);
removeByPos(list,2);
printList(list,myPrint);
int idx = findElement(list,(void*)&p1);
printf("??%d\n",idx);
idx = findElement(list,(void*)&p5);
printf("??%d\n",idx);
//清空
freeList(list);
}int main()
{test();
return 0;
}
推荐阅读
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- C/C++|C/C++ basis 02
- Qt实战|Qt+OpenCV联合开发(二十一)--图像翻转与旋转
- Qt实战|Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取
- Qt实战|Qt+OpenCV联合开发(十三)--通道分离与合并
- opencv|Qt+OpenCV联合开发(十六)--图像几何形状绘制
- Qt实战|Qt+OpenCV联合开发(十七)--随机数与随机颜色
- SNAT的MASQUERADE地址选择与端口选择
- IPTABLES的连接跟踪与NAT分析
- IPVS分析