#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<string.h>
typedef struct Listnode
{
int data;
struct Listnode* pnext;
}node,*pnode;
pnode Creatlist()
{
pnode phead = (pnode)malloc(sizeof(node));
phead->data = 2;
phead->pnext = NULL;
int len = 0;
int value = 0;
pnode pTail = phead;
printf("input data len");
scanf("%d",&len);
for (int i = 0; i < len; i++)
{
pnode pnew = (pnode)malloc(sizeof(node));
printf("input value");
scanf("%d",&value);//一定要带取址符号
pnew->data = value;
pTail->pnext= pnew;
pnew->pnext = NULL;
pTail = pnew;
}
return phead;
}
void Printlist(pnode phead)
{
if (phead == NULL) return;
pnode p = phead;
while (p->pnext != NULL)
{
printf("node's value is%d\n",p->pnext->data);
p = p->pnext;
}
}
int Getlengthoflist(pnode phead)
{
if (phead == NULL)return 0;
int length = 0;
pnode p = phead->pnext;
while (p != NULL)
{
length++;
p = p->pnext;
}
return length;
}
int Delenode(pnode phead, int pos)//删除节点时,头结点和尾节点要分开处理
{
if (phead == NULL)return 0;
int len = Getlengthoflist(phead);
pnode p = phead;
int result = 0;
if (pos == 0) //删除头结点
{
p->pnext = NULL;
result = -1;
return result;
}
if (pos == len)//删除尾节点
{
while (pos != 1)
{
pos--;
p = p->pnext;
}
pnode deletnode = p->pnext;
result = deletnode->data;
p->pnext = NULL;
free(deletnode);
return result;
}
if ((pos > 0) && (pos <len))
{
while (pos != 1)
{
pos--;
p = p->pnext;
}
}
pnode delenode = p->pnext;
p->pnext = delenode->pnext;
result = delenode->data;
free(delenode);
return result;
}
/*pnode Deltvaluenode(pnode phead, int value)// 删除链表中节点值等于value的节点
{
pnode cur = phead;
pnode pre = NULL;
pnode temp = NULL;
while (cur!=NULL)
{
if (cur->pnext != NULL)
{
if (cur->pnext->data == value)// 这样写有错,要是最后一个节点的值是VALUE呢?会出错
{
pre = cur;
temp = cur->pnext;
pre->pnext = temp->pnext;
free(temp);
temp = NULL;
}
else
cur = cur->pnext;
}
else
{
if (cur->data == value){"找不到上一个节点"}
}
}
return phead;
}*/
pnode Deltvaluenode(pnode phead, int value)// 删除链表中节点值等于value的节点
{
pnode cur = phead;
pnode pre = NULL;
pnode temp = NULL;
while (cur != NULL)
{
if ((pre == NULL) && (cur->data == value))
{
pre = phead;
free(pre);
pre = NULL;
cur = cur->pnext;
phead = cur;
}
if (cur->data == value)
{
pre->pnext = cur->pnext;
free(cur);
cur = pre->pnext;
}
else
{
pre = cur;
cur = cur->pnext;
}
}
return phead;
}
pnode Insertlist(pnode phead,int pos,int value)//在pos之后插入节点
{
int len = Getlengthoflist(phead);
pnode p = phead;
pnode pnew = (pnode)malloc(sizeof(node));
pnew->data = value;
pnew->pnext = NULL;
if ((pos >=0) && (pos < len))
{
while (pos != 0)
{
pos--;
p = p->pnext;
}
pnew->pnext = p->pnext;
p->pnext = pnew; //这两句话的顺序不可以颠倒
}
if (pos == len)
{
while (pos != 0)
{
pos--;
p = p->pnext;
}
pnew->pnext = NULL;
p->pnext = pnew;
}
return phead;
}
pnode InsertNode(pnode phead,int value)//在有序的链表中插入一个新的节点,
{
pnode cur=phead;
pnode pre=NULL;
while((cur!=NULL)&&cur->data<value)
{
pre = cur;
cur = cur->pnext;
}
pnode pnew = (pnode)malloc(sizeof(node));
pnew->data = value;
pnew->pnext = NULL;
if (pre != NULL)
{
pre->pnext = pnew;
pnew->pnext = cur;
return phead;
}
else
{
pnew->pnext = cur;
return pnew;
}
}
pnode sortlist(pnode phead)//链表的冒泡排序
{
int len = Getlengthoflist(phead);
for (int i = 0; i < len-1; i++)
{
pnode p = phead->pnext;
for (int j = 0; j < len - i - 1; j++)
{
if (p->data <= p->pnext->data)
p = p->pnext;
else
{
int temp = p->data;
p->data = p->pnext->data;
p->pnext->data = temp;
p = p->pnext;
}
}
}
return phead;
}
pnode reverselist(pnode phead)//反转链表,改变链表的结构. 需要三个指针
{
// pnode prehead =NULL;
pnode cur = phead->pnext;
pnode P_next = NULL;
pnode P_pre = NULL;
while (cur != NULL)
{
P_next = cur->pnext;//一定要先保存下来下一个节点
if (P_next == NULL)
{
phead->pnext= cur;
}
cur->pnext = P_pre;
P_pre = cur;
cur = P_next;
}
return phead;
}
Status InitList1(LinkList &L) //等价于Node *L
{
L = (LinkList)malloc(sizeof(node)); /* 产生头结点,并使L指向此头结点 */
if (!L) /* 存储分配失败 */
return 0;
L->pnext = NULL; /* 指针域为空 */
return 1;
}
//初始化表头,用二级指针
Status InitList2(LinkList *L) //等价于Node **L
{
*L = (LinkList)malloc(sizeof(node)); /* 产生头结点,并使L指向此头结点 */
if (!(*L)) /* 存储分配失败 */
return 0;
(*L)->pnext = NULL; /* 指针域为空 */
return 1;
}
Status ClearList2(LinkList L)
{
LinkList p, q;
p = L->pnext; /* p指向第一个结点 */
while (p) /* 没到表尾 */
{
q = p->pnext;
free(p);
p = q;
}
L->pnext = NULL; /* 头结点指针域为空 */
return 1;
}
Status ListInsert2(LinkList L, int i, int e)
{
int j;
LinkList p, s;
p = L;
j = 1;
while (p && j < i) /* 寻找第i个结点 */
{
p = p->pnext;
++j;
}
if (!p || j > i)
return 0; /* 第i个元素不存在 */
s = (LinkList)malloc(sizeof(node)); /* 生成新结点(C语言标准函数) */
s->data = e;
s->pnext = p->pnext; /* 将p的后继结点赋值给s的后继 */
p->pnext = s; /* 将s赋值给p的后继 */
return 1;
}
Status ListTraverse(LinkList L)
{
LinkList p = L->pnext;
while (p)
{
printf("%d",p->data);
p = p->pnext;
}
printf("\n");
return 1;
}
int main()
{
int deledata = 0;
pnode plist = Creatlist();
Printlist(plist);
//plist = Insertlist(plist, 3, 6);
//Printlist(plist);
printf("\n\n");
//plist = InsertNode(plist, 1);
//Printlist(plist);
//plist=sortlist(plist);
plist = reverselist(plist);
Printlist(plist);
//plist = Insertlist(plist, 0, 6);
//Printlist(plist);
//printf("\n\n");
//plist = Insertlist(plist, 5, 6);
//Printlist(plist);
//deledata=Delenode(plist,3);
//Printlist(plist);
//printf("deledata is%d",deledata);
//deledata = Delenode(plist, 5);
//Printlist(plist);
//printf("deledata is%d", deledata);
//deledata = Delenode(plist, 0);
//Printlist(plist);
//printf("deledata is%d", deledata);
//plist = Deltvaluenode(plist, 3);
//Printlist(plist);
system("pause");
}
2、给定一个链表和一个节点的指针,定义一个在O(1)时间内删除该节点的函数。
删除节点思路有二:常规的做法是找到待删节点的前一个节点
第二:不用找到待删节点的前一个节点,而是把待删节点i的后一个节点J中的内容复制到节点i内,然后再把i节点的next指向节点J的下一个节点,再删除节点J.
还有一个问题,如果基于第二思路,当删除的节点是链表的尾节点时,我们还是需要顺序遍历链表,找到尾节点的前一个节点。
3、链表的初始化和销毁时,要用到二级指针或者一级指针的引用。
简单来说,修改头指针则必须传递头指针的地址,否则传递头指针即可。这与普同的变量类似,当需要修改变量的值时,需要传递其地址,否则传递普通变量即可。使用二级指针,可以很方便的修改传入的一级指针的值。如果用一级指针,则只能通过指针修改指针所指向的内容,无法修改指针的值,也就是指针所指向的内存的内容,所以初始化链表和销毁链表时 需要二级指针或者一级指针的引用。
4/判断链表是否有环?以及环的入口位置?
bool Iscirclelist(pnode phead)
{
if (phead == NULL)return false;
pnode cur = phead->pnext;
while (cur)
{
if (cur->pnext == phead)return true;
cur = cur->pnext;
}
return false;
}
bool Iscirclist1(pnode phead)
{
if (phead == NULL)return false;
pnode plow =phead->pnext;
pnode pquick = phead->pnext->pnext;
while (pquick != NULL&&pquick->pnext != NULL)
{
pquick = pquick->pnext->pnext;
plow = plow->pnext;
if (pquick == plow)
return true;
}
return false;
}
//如何来确定循环链表的入口地址
//环的接入点:碰撞点p到连接点的距离 = 头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,
//相遇的那个点就是连接点。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{ ListNode* fast,*slow;
fast=pHead;
slow=pHead;
while(fast!=NULL&&fast->next!=NULL)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{ fast=pHead;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
if(slow==fast)
return slow;
}
}
return NULL;
}
};