我最近在学习数据结构中的链表中的一些收获,如下所示。
1.引入我们的头文件,函数申明,及实现;
#pragma once
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include<stdbool.h>
#define DCList_ElemType int
typedef struct DCListNode
{
DCList_ElemType data;
struct DCListNode* prev;
struct DCListNode* next;
}DCListNode;
typedef DCListNode* DCList;
//函数申明
void DCListInit(DCList* ph);
void DCListPushBack(DCList ph, DCList_ElemType x);
void DCListPushFront(DCList ph, DCList_ElemType x);
void DCListPopBack(DCList ph);
void DCListPopFront(DCList ph);
DCListNode* DCListFind(DCList ph, DCList_ElemType x);
void DCListDeleteByVal(DCList ph, DCList_ElemType x);
int DCListLength(DCList ph);
void DCListInsertByVal(DCList ph, DCList_ElemType x);
void DCListClear(DCList ph);
void DCListReverse(DCList ph);
void DCListShow(DCList ph);
void DCListDestroy(DCList* ph);
//函数实现
void DCListInit(DCList* ph)
{
assert(ph != NULL);
(*ph) = (DCListNode*)malloc(sizeof(DCListNode));
assert(*ph != NULL);
(*ph)->next = (*ph)->prev = (*ph);
}
void DCListPushBack(DCList ph, DCList_ElemType x)
{
DCListNode* s = (DCListNode*)malloc(sizeof(DCListNode));
assert(s != NULL);
s->data = x;
s->next = ph;
s->prev = ph->prev;
ph->prev->next = s;
ph->prev = s;
}
void DCListPushFront(DCList ph, DCList_ElemType x)
{
DCListNode* s = (DCListNode*)malloc(sizeof(DCListNode));
assert(s != NULL);
s->data = x;
s->next = ph->next;
s->prev = ph;
ph->next = s;
s->next->prev= s;
}
void DCListShow(DCList ph)
{
DCListNode* p = ph->next;
while (p != ph)
{
printf("%d-->", p->data);
p = p->next;
}
printf("Over\n");
}
int DCListLength(DCList ph)
{
DCListNode* p = ph->next;
DCList_ElemType count = 0;
while (p != ph)
{
++count;
p = p->next;
}
return count;
}
void DCListPopBack(DCList ph)
{
assert(ph != NULL);
DCListNode* p = ph->prev;
ph->prev = ph->prev->prev;
ph->prev->next = ph;
free(p);
}
void DCListPopFront(DCList ph)
{
assert(ph != NULL);
DCListNode* p = ph->next;
ph->next = ph->next->next;
ph->next->prev = ph;
free(p);
}
void DCListInsertByVal(DCList ph, DCList_ElemType x)
{
assert(ph != NULL);
DCListNode* s = (DCListNode*)malloc(sizeof(DCListNode));
assert(s != NULL);
s->data = x;
DCListNode* p = ph->next;
while (p != ph && p->data < x)
p = p->next;
s->next = p;
s->prev = p->prev;
s->prev->next = s;
p->prev = s;
}
void DCListDeleteByVal(DCList ph, DCList_ElemType x)
{
assert(ph != NULL);
DCListNode* p = DCListFind(ph, x);
if (p != NULL)
{
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
}
}
DCListNode* DCListFind(DCList ph, DCList_ElemType x)
{
assert(ph != NULL);
DCListNode* p = ph->next;
while (p != ph)
{
if (p->data == x)
return p;
p = p->next;
}
return NULL;
}
void DCListReverse(DCList ph)
{
assert(ph != NULL);
DCListNode* p = ph->next;
DCListNode* q = p->next;
ph->prev = p;
p->next = ph;
while (q != ph)
{
p = q;
q = q->next;
p->next = ph->next;
p->prev = ph;
ph->next->prev = p;
ph->next = p;
}
}
//有问题的
/*void DCListClear(DCList ph)
{
assert(ph != NULL);
DCListNode* p = NULL; //只是申请了指针节点
p = ph->next;
while (p != ph)
{
DCListNode* q = p;
p = p->next; //p非链式结构,后面没有节点,指向非法故产生警告
free(p);
}
}*/
void DCListClear(DCList ph)
{
assert(ph != NULL);
DCListNode* p = NULL;
p = ph->next;
while (p != ph)
{
DCListNode* q = p;
p->prev->next = p->next;
p->next->prev = p->prev;
p = p->next;
free(q);
}
}
void DCListDestroy(DCList* ph)
{
assert(ph != NULL);
DCListClear(*ph);
free(*ph);
*ph = NULL;
}
2.主函数对链表功能的调用。
#include"DcList.h"
int main()
{
DCList mylist;
DCListInit(&mylist);
int Select = 0;
int pos = 0;
int x = 0;
DCListNode* p = NULL;
while (1)
{
printf("**************************************\n");
printf("*[1] PushBack [2] PushFront *\n");
printf("*[3] ShowList [4] Length *\n");
printf("*[5] PopBack [6] PopFront *\n");
printf("*[7] Insert_Val [8] Delate_Val *\n");
printf("*[9] Find [10] Reverse *\n");
printf("*[11] [12] Clear *\n");
printf("**********[0] Quit System*************\n\n");
printf("请选择\n");
scanf_s("%d", &Select);
if (Select == 0)
{
printf("已经退出\n");
return 0;
}
switch (Select)
{
case 1:
printf("请输入要尾插数据(以-1结束)\n");
while (scanf_s("%d", &x), x != -1)
{
DCListPushBack(mylist, x);
}
break;
case 2:
printf("请输入要头插数据(以-1结束)\n");
while (scanf_s("%d", &x), x != -1)
{
DCListPushFront(mylist, x);
}
break;
case 3:
printf("显示链表\n");
DCListShow(mylist);
break;
case 4:
x = DCListLength(mylist);
printf("链表长度为%d\n", x);
break;
case 5:
DCListPopBack(mylist);
break;
case 6:
DCListPopFront(mylist);
break;
case 7:
printf("输入你想插入的值\n");
scanf_s("%d", &x);
DCListInsertByVal(mylist, x);
break;
case 8:
printf("输入你想删除的值\n");
scanf_s("%d", &x);
DCListDeleteByVal(mylist, x);
break;
case 9:
printf("输入你想查找的值\n");
scanf_s("%d", &x);
p = DCListFind(mylist, x);
if (p == NULL)
{
printf("没有该值\n");
break;
}
printf("你想查找的值的地址\n");
printf("%p\n", &p);
break;
case 10:
DCListReverse(mylist);
printf("链表的逆置已完成\n");
break;
case 11:
printf("空操作\n");
break;
case 12:
DCListClear(mylist);
break;
default:
break;
}
}
DCListDestroy(&mylist);
}
感谢大家观看!