学习数据结构--单链表的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/luolan_hust/article/details/68936206
#include <iostream>
#include <stdio.h>
using namespace std;

//****对于一个线性表,通常需要实现的操作有:新建一个空表、销毁一个表,清空一个表,判断是否为空
//****获得表的长度,查找指定位置的元素值、查找指定元素的位置、返回前驱元素,返回后继元素
//****插入、删除、排序、逆序、遍历一遍
//****复杂操作:两个表合并成为一个表,一个表拆开成两个表,复制一个线性表


//2. 写一个单链表,线性表的链式存储结构
 struct ListNode
{
int data;
ListNode * next;
};

 bool IsListNodeEmpty(ListNode*phead)
 {
//判断一个链表是否为空,总是用头指针来表示一个链表
if (phead == NULL)
{
return true;
}
else
{
return false;
}
 }

 void PrintListNode(ListNode*phead)
 {
if (IsListNodeEmpty(phead))//打印链表
{
printf("当前链表是一个空表!\n");
return;
}
else
{
printf("当前链表打印结果:\n");
while (phead != NULL)
{
printf("%d\t", phead->data);
phead = phead->next;
}
printf("\n");
return;
}
 }


 ListNode* CreateList( )
 {
int num;
ListNode *head = NULL;
ListNode*plastnode = NULL;
ListNode*pnewnode = NULL;
printf("请输入要创建的链表节点数目:\n");
scanf_s("%d", &num);
for (int i = 0; i < num; i++)
{
pnewnode = (ListNode*)malloc(sizeof(struct ListNode));
if (pnewnode==NULL)
{
printf("分配内存失败!\n");
return NULL;
}
printf("请输入节点数据值:\n");
scanf_s("%d", &pnewnode->data);
if (head==NULL)
{
head = pnewnode;
plastnode = pnewnode;
}
else
{
plastnode->next = pnewnode;
plastnode = pnewnode;
}
}
plastnode->next = NULL;
printf("链表创建成功!\n");
PrintListNode(head);
return head;
 }

 ListNode* ClearListNode( ListNode*phead)
 {
if (!IsListNodeEmpty(phead))//清除这个链表等于销毁这个链表
{
ListNode*pnode = NULL;
while (phead!=NULL)
{
pnode = phead->next;
free(phead);
phead = pnode;
}
printf("当前链表已经清除!\n");
return phead;
}
else
{
printf("当前链表是一个空表,不执行清除!\n");
return NULL;
}
 }

 int GetListNodeLength(ListNode*phead)
 {
if (IsListNodeEmpty(phead))//返回链表长度
{
printf("当前链表是一个空表!\n");
return 0;
}
else
{
int count = 0;
while (phead!=NULL)
{
count++;
phead = phead->next;
}
return count;
}
 }

 //按位置查找元素值
 int GetListNodeEnum(ListNode*phead,int index)
 {
if (IsListNodeEmpty(phead))//判断链表是否为空
{
printf("当前链表是一个空表!\n");
return -1;
}
int length = GetListNodeLength(phead);
if (index<0 || index >length)
{
printf("输入的位置超出链表长度!\n");
return -1;
}
int i= 0;
while (phead != NULL)
{
i++;
if (i==index)
{
break;
}
phead = phead->next;
}
printf("找到输入的位置%d元素为:%d\n",index, phead->data);
return phead->data;
 }

 //按元素查找链表节点
 int GetListNodeLocate(ListNode*phead,int evalue)
 {
int index = 0;
if (phead==NULL)
{
printf("当前是一个空表!\n");
}
while (phead!=NULL)
{
index++;
if (evalue==phead->data)
{
break;
}
phead = phead->next;
}
if (phead==NULL)
{
printf("当前链表中没有该数据值对应的节点!\n");
}
return index;
 }

 //修改链表中第index个节点的元素值,成功返回1,失败返回0
 int ModifyListNode(ListNode*phead, int index,int evalue)
 {
if (IsListNodeEmpty(phead))//判断链表是否为空
{
printf("当前链表是一个空表!\n");
return -1;
}
int length = GetListNodeLength(phead);
if (index<0 || index >length)
{
printf("输入的位置超出链表长度!\n");
return 0;
}
int i = 0;
while (phead->next != NULL)
{
i++;
if (i == index)
{
break;
}
phead = phead->next;
}
if (phead!=NULL)
{
phead->data = evalue;
return 1;
}
else
{
return 0;
}
 }

 //链表表头插入一个元素
 ListNode* PreInsertListNode(ListNode*phead, int evalue)
 {
ListNode*prenode = (ListNode*)malloc(sizeof(struct ListNode));//可以考虑把初始化一个节点写成一个init 函数
prenode->data = evalue;
if (phead==NULL)
{
prenode->next = NULL;
return prenode;
}
else
{
prenode->next = phead;
return prenode;
}
 }


 //链表末尾插入一个元素
 ListNode* TailInsertListNode(ListNode*phead, int evalue)
 {
ListNode*tailnode = (ListNode*)malloc(sizeof(struct ListNode));
tailnode->data = evalue;
tailnode->next = NULL;
if (phead==NULL)
{
return tailnode;
}
else
{
ListNode*tempnode = phead;
while (tempnode->next != NULL)
{
tempnode = tempnode->next;
}
tempnode->next = tailnode;
return phead;
}
 }


 //返回前驱元素
 ListNode *GetPreNode(ListNode*phead,ListNode*ipnode)
 {
if (phead==NULL)
{
printf("链表为空,没有前驱节点!\n");
return NULL;
}
else
{
if (ipnode==phead)
{
printf("当前节点是头节点,没有前驱节点!\n");
return NULL;
}
else
{
ListNode*tempnode = phead;
bool isfind = false;
while (tempnode->next != NULL)
{
if (tempnode->next==ipnode)
{
isfind = true;
return tempnode;
}
else
{
tempnode = tempnode->next;
continue;
}
}
if (isfind==false)
{
printf("在当前链表中没有找到其前驱节点!\n");
return NULL;
}
}
}
 }


 //返回后继元素
 ListNode *GetNextNode(ListNode*phead, ListNode*ipnode)
 {
if (NULL == phead)
{
printf("链表为空!\n");
return NULL;
}
else
{
if (ipnode->next!=NULL)
{
return ipnode->next;
}
else
{
printf("该节点是尾部节点,没有后继!\n");
return NULL;
}
}
 }


 //在某一节点之前插入
 ListNode *InsertNodePre(ListNode*phead, ListNode*ipnode, int insertdata)
 {
ListNode*insertnode = (ListNode*)malloc(sizeof(ListNode));
insertnode->data = insertdata;
insertnode->next = NULL;
if (phead==NULL)
{
return insertnode;
}
else if (phead == ipnode)
{
insertnode->next = phead;
return insertnode;
}
else
{
ListNode*theprenode = GetPreNode(phead, ipnode);
if (theprenode!=NULL)
{
theprenode->next = insertnode;
insertnode->next = ipnode;
return phead;
}
else
{
printf("该节点不属于链表,无法向前插入!\n");
return NULL;
}
}
 }


 //某一节点之后插入
 ListNode *InsertNodeNext(ListNode*phead, ListNode*ipnode, int insertdata)
 {
ListNode*insertnode = (ListNode*)malloc(sizeof(ListNode));
insertnode->data = insertdata;
insertnode->next = NULL;
if (phead == NULL)
{
return insertnode;
}
else if ( ipnode->next==NULL)
{
ipnode->next = insertnode;
return phead;
}
else
{
ListNode*thenextnode = ipnode->next;
ipnode->next = insertnode;
insertnode->next = thenextnode;
return phead;
}
 }


 //删除某一节点
 ListNode* DeleteListNode(ListNode*phead, ListNode*ipnode)
 {
if (phead==NULL || ipnode==NULL)
{
printf("删除失败,请检查输入!\n");
return phead;
}
else if (ipnode==phead)
{
ListNode*tempnode = phead->next;//如果这是第一个节点
free(phead);
phead = NULL;
ipnode = NULL;
return tempnode;
}
else
{
ListNode*thenextnode = ipnode->next;
ListNode*theprenpde = GetPreNode(phead, ipnode);
if (theprenpde!=NULL)
{
free(ipnode);
ipnode = NULL;
theprenpde->next = thenextnode;
return phead;
}
else
{
printf("输入节点不在链表里 ,删除失败,请检查输入!\n");
return phead;
}
}
 }
 //链表排序
 ListNode*SortListNode(ListNode*phead)//升序
 {
int length= GetListNodeLength(phead);
if (length==0 || length==1)
{
return phead;
}
//使用冒泡排序,两个相邻的比较。一种只交换数据,一种需要交换指针
ListNode*tnode1=NULL;
ListNode*tnode2=NULL;
for (tnode1 = phead; tnode1 != NULL; tnode1 = tnode1->next)
{
for (tnode2 = phead; tnode2->next != NULL; tnode2=tnode2->next)
{
if (tnode2->data > tnode2->next->data)
{
int temp = tnode2->data;
tnode2->data = tnode2->next->data;
tnode2->next->data = temp;
}
}
}
return phead;
 }
 //链表逆序
 ListNode*ReverseListNode(ListNode*phead)
 {
if (phead==NULL)
{
printf("链表为空!\n");
return phead;
}
else
{
ListNode*newlisthead = NULL;//声明一个空表
ListNode*tempnode = phead;
ListNode*thenode = NULL;
while (tempnode != NULL)
{
thenode = tempnode;
tempnode = tempnode->next;
thenode->next=newlisthead;
newlisthead = thenode;
}
return newlisthead;
}
 }


 //主函数中测试该顺序表
 bool menu2(ListNode *L)
 {
  int i;
int a = 0;
  system("cls");
  printf("*********进入单链表测试系统***********\n");
  printf("0---创建单链表\n");
  printf("1---打印单链表\n");
  printf("2---向后插入一个节点\n");
  printf("3---按位置删除\n");
  printf("4---按位置查找\n");
  printf("5---按值查找\n");
  printf("6---清除单链表\n");
  printf("7---获取单链表长度\n");
printf("8---修改某个节点数据\n");
  printf("9---冒泡排序链表\n");
printf("10---逆序链表\n");
printf("11---尾部插入\n");
printf("12---头部插入\n");
printf("13---向前插入一个节点\n");
printf("14---退出\n");
  printf("*******************************\n");
  scanf_s("%d", &i);
  switch (i){
  case 0:
L=CreateList();
system("pause");
  menu2(L);
  case 1:
PrintListNode(L);
  system("pause");
menu2(L);
  case 2:
InsertNodeNext(L, L->next, 0);
PrintListNode(L);
system("pause");
menu2(L);
  case 3:
DeleteListNode(L, L->next);
PrintListNode(L);
  system("pause");
menu2(L);
  case 4:
a=GetListNodeEnum(L, 1);
PrintListNode(L);
  system("pause");
menu2(L);
  case 5:
a=GetListNodeLocate(L, 0);
printf("元素0的位置是:%d\n", a);
PrintListNode(L);
  system("pause");
  menu2(L);
  case 6:
L=ClearListNode(L);
PrintListNode(L);
  system("pause");
menu2(L);
  case 7:
a=GetListNodeLength(L);
printf("链表长度是:%d\n", a);
  system("pause");
menu2(L);
  case 8:
ModifyListNode(L, 1, 0);
PrintListNode(L);
system("pause");
menu2(L);
case 9:
L=SortListNode(L);
PrintListNode(L);
system("pause");
menu2(L);
case 10:
L=ReverseListNode(L);
PrintListNode(L);
system("pause");
menu2(L);
case 11:
L=TailInsertListNode(L,100);
PrintListNode(L);
system("pause");
menu2(L);
case 12:
L=PreInsertListNode(L,100);
PrintListNode(L);
system("pause");
menu2(L);
case 13:
L=InsertNodePre(L, L, 0);
PrintListNode(L);
system("pause");
menu2(L);
case 14:
exit(0);
  }
  return 1;
 }


 void main()
 {
ListNode*L = NULL;
menu2(L);
 }

猜你喜欢

转载自blog.csdn.net/luolan_hust/article/details/68936206
今日推荐