链表相对于线性表的优点就在于插入和删除十分方便。
那么我用一个有意思的比喻来描述一下这个过程。
插入:
小红和小琴是好闺蜜,她们天天都拉着手(找男的比喻不大好啊,23333)
咳咳,就是这样(图中蓝色上衣的是小红,绿色裙子的是小琴)
小红的手和小琴的手拉着一起
之后有一个女生名字叫小美也想加入她们,和她们成为好闺蜜,那么就成了这样了 →_→
(我不是故意的)
这样小红的手和小琴的手就不拉在一起了,反而小红的手和小美的左手拉在一起,小美的右手与小琴的手拉在一起了。(这里的左右手是我们的视角看到的左右手)
现在把小红、小琴、小美各作为一个节点即节点a,节点b,节点k。
原来的情形是小红和小琴的手天天拉着:
a->next = b;
那么之后呢小美插进两人之间:
k->next = a->next; //小美的右手牵着曾经小红牵着的小琴
a->next = k; //小红牵着小美的左手
void Push_L(LinkList &L, int data, int i)
{
Node *p = L;
int j = 1;
while(p&&j<i)
{
p=p->next;
++j;
}
Node *q = (LinkList)malloc(sizeof(Node));
q->data = data;
q->next = p->next;
p->next = q;
}
删除:
因为小红和小琴两人嫉妒小美的貌美,就不接受她继续在她们两者之间了,那么就要把小美“踢”出去。
a->next = k->next;//小红继续和小琴牵着手
free(k); //小美成了独立人2333
void Delete_L(LinkList &L,int i)
{
LinkList p = L;
if(i<0)
printf("INFEASIBLE");
int j = 1;
while(p&&j<i)
{
p=p->next;
++j;
}
Node *q = p->next;
p->next = p->next->next;
free(q);
}
实现的整个代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *next;
}Node,*LinkList;
/*创建一个新链表*/
void CreatList_L(LinkList &L,int n)
{
int a;
L = (LinkList)malloc(sizeof(Node));
L->next = NULL;//建立一个带头结点的单链表
Node *q = L;
for(int i=0;i<n;i++)
{
Node *p = (LinkList)malloc(sizeof(Node));
scanf("%d",&a);
p->data = a;
q->next = p;
p->next=NULL;
q = q->next;
}
}
/*在链表的第i处插入一个元素*/
void Push_L(LinkList &L, int data, int i)
{
Node *p = L;
int j = 1;
while(p&&j<i)
{
p=p->next;
++j;
}
Node *q = (LinkList)malloc(sizeof(Node));
q->data = data;
q->next = p->next;
p->next = q;
}
/*删除第i个元素*/
void Delete_L(LinkList &L,int i)
{
Node *p = L;
if(i<0)
printf("INFEASIBLE");
int j = 1;
while(p&&j<i)
{
p=p->next;
++j;
}
Node *q = p->next;
p->next = p->next->next;
free(q);
}
void Traverse_L(LinkList &L)
{
LinkList p = L->next;
while(p!=NULL){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}//正序遍历整个链表
int main()
{
LinkList L;
int n;
printf("输入要创建的链表中的元素个数:\n");
scanf("%d",&n);
printf("输入%d个元素:\n",n);
CreatList_L(L,n);
printf("遍历整个链表\n");
Traverse_L(L);
int push_data,push_i;
printf("输入你想要插入的元素和它的插入位置:\n");
{
scanf("%d%d",&push_data,&push_i);
}
Push_L(L, push_data, push_i);
printf("插入后的链表遍历为:\n");
Traverse_L(L);
int del_i;
printf("输入要删除链表中的第几个元素:\n");
scanf("%d", &del_i);
Delete_L(L, del_i);
printf("删除后的链表遍历为:\n");
Traverse_L(L);
return 0;
}
效果图:
———————————————分割线————————————————–
今天数据结构上机实验要实现字符串链表,改一下数据类型就行,新增头插法:
(Ps:老师竟然让手抄实验报告,我内心是拒绝的,让我们照着敲挺没意义的,想学的人照样会学,不学的人你给他代码,照着打一遍后就忘了,何必呢?我觉得最好的学习方式就是先自己思考,实在不会再提供提示或参考,这样效果是最佳的!!)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node{
char data[10];
struct node *next;
}Node,*LinkList;
/*创建一个新链表(尾插法)*/
void CreatList_tail(LinkList &L)
{
L = (LinkList)malloc(sizeof(Node));
L->next = NULL;//建立一个带头结点的单链表
Node *q = L;
while(1)
{
char ch[10];
printf("Input # to end ");
printf("Please input Node_data:");
Node *p = (LinkList)malloc(sizeof(Node));
scanf("%s", ch);
if(strcmp(ch, "#") == 0) break;
strcpy(p->data, ch);
q->next = p;
p->next = NULL;
q = q->next;
}
return;
}
/*头插法*/
void CreatList_head(LinkList &L)
{
L = (LinkList)malloc(sizeof(Node));
L->next = NULL;//建立一个带头结点的单链表
while(1)
{
char ch[10];
printf("Input # to end ");
printf("Please input Node_data:");
Node *p = (LinkList)malloc(sizeof(Node));
scanf("%s", ch);
if(strcmp(ch, "#") == 0) break;
strcpy(L->data, ch);
p->next = L;
L = p;
}
return;
}
/*按值查找结点,找到则返回该结点的位置,否则返回NULL*/
Node *LocateNode(LinkList L, char *ch)
{
Node *p = L;
while(p!=NULL && strcmp(p->data, ch) != 0)
{
p = p->next;
}
return p;
}
/*在链表的第i处插入一个元素*/
void Push_L(LinkList &L, char *ch, int i)
{
Node *p = L;
int j = 0;
while(p&&j<i)
{
p=p->next;
++j;
}
Node *q = (LinkList)malloc(sizeof(Node));
strcpy(q->data, ch);
q->next = p->next;
p->next = q;
}
/*删除元素*/
void Delete_L(LinkList &L, char *ch)
{
Node *p = L;
while(strcmp(p->next->data, ch)!=0)
{
p=p->next;
}
Node *q = p->next;
p->next = p->next->next;
free(q);
}
void Traverse_L(LinkList &L)
{
LinkList p = L->next;
while(p!=NULL){
printf("%s, ",p->data);
p = p->next;
}
printf("\n");
}//正序遍历整个链表
//void Inverted_L(LinkList &L1,LinkList &L2)
//{
// Node *p1 = L1->next;
// L2 = (LinkList)malloc(sizeof(Node));
// L2->next=NULL;
// while(p1!=NULL)
// {
// Node *p2 = (LinkList)malloc(sizeof(Node));
// strcpy(p2->data, p1->data);
// p2->next=L2->next;
// L2->next=p2;
// p1=p1->next;
// }
//}
int main()
{
LinkList L1;
char num[5];
char ch[10];
CreatList_head(L1);
Traverse_L(L1);
printf("Delete node (y/n):");
scanf("%s",num);
if(strcmp(num, "y")==0 || strcmp(num, "Y")==0)
{
printf("Please input Delete_data:");
scanf("%s",ch);
Delete_L(L1, ch);
Traverse_L(L1);
}
printf("Insert node (y/n):");
scanf("%s", num);
if(strcmp(num, "y")==0 || strcmp(num, "y")==0)
{
char push_data[10];
int push_i;
printf("Please input a New Node_data:");
scanf("%s",push_data);
printf("postion :");
scanf("%d",&push_i);
Push_L(L1, push_data, push_i);
Traverse_L(L1);
}
return 0;
}