带头双向循环链表的实现
phead中的data不能存储数据的个数,因为数据的类型不能确定,若是char类型,phead的data将无法存储足够多的有效数据的个数(链表多于128 )
头文件与函数声明
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int BHLLDataType;
typedef struct BHLLNode
{
BHLLDataType data;
struct BHLLNode* next;
struct BHLLNode* prev;
}BHLLNode;
BHLLNode* CreateNode(BHLLDataType x);
BHLLNode* BHLLInit();
void BHLLDestroy(BHLLNode* head);
void BHLLPrint(BHLLNode* head);
void BHLLPushBack(BHLLNode* head,BHLLDataType x);
void BHLLPushFront(BHLLNode* head,BHLLDataType x);
void BHLLPopBack(BHLLNode* head);
void BHLLPopFront(BHLLNode* head);
BHLLNode* BHLLFnind(BHLLNode* head,BHLLDataType x);
void BHLLInsert(BHLLNode* pos,BHLLDataType x);
void BHLLErase(BHLLNode* pos);
函数实现
#define _CRT_SECURE_NO_WARNINGS
#include"Bidirectional head-linked list.h"
BHLLNode* CreateNode(BHLLDataType x)
{
BHLLNode* newnode = (BHLLNode*)malloc(sizeof(BHLLNode));
if (newnode == NULL)
{
perror("malloc failt");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
BHLLNode* BHLLInit()
{
BHLLNode* newnode = CreateNode(0);
newnode->next = newnode;
newnode->prev = newnode;
return newnode;
}
void BHLLDestroy(BHLLNode* head)
{
BHLLNode* cur = head->next;
while (cur != head)
{
BHLLNode* freenode = cur;
cur = cur->next;
free(freenode);
freenode = NULL;
}
}
void BHLLPrint(BHLLNode* head)
{
BHLLNode* cur = head->next;
printf("phead<=>");
while (cur != head)
{
printf("%d<=>", cur->data);
cur = cur->next;
}
printf("\n");
}
void BHLLPushBack(BHLLNode* head, BHLLDataType x)
{
BHLLNode* newnode = CreateNode(x);
newnode->prev = head->prev;
newnode->next = head;
head->prev->next = newnode;
head->prev = newnode;
}
void BHLLPushFront(BHLLNode* head, BHLLDataType x)
{
assert(head);
BHLLNode* newnode = CreateNode(x);
newnode->next = head->next;
newnode->prev = head;
head->next->prev = newnode;
head->next = newnode;
}
void BHLLPopBack(BHLLNode* head)
{
BHLLNode* tail = head->prev;
tail->prev->next = head;
head->prev = tail->prev;
free(tail);
}
void BHLLPopFront(BHLLNode* head)
{
assert(head);
BHLLNode* freenode = head->next;
freenode->next->prev = head;
head->next = freenode->next;
free(freenode);
}
BHLLNode* BHLLFnind(BHLLNode* head,BHLLDataType x)
{
assert(head);
BHLLNode* cur = head->next;
while (cur!=head)
{
if (cur->data == x)
return cur;
cur = cur->next;
}
printf("找不到");
return NULL;
}
void BHLLInsert(BHLLNode* pos,BHLLDataType x)
{
assert(pos);
BHLLNode* pprev = pos->prev;
BHLLNode* newnode = CreateNode(x);
pprev->next = newnode;
newnode->prev = pprev;
newnode->next = pos;
pos->prev = newnode;
/*newnode->next = pos;
newnode->prev = pprev;
pprev->next = newnode;
pos->prev = newnode;*/
}
void BHLLErase(BHLLNode* pos)
{
BHLLNode* pprev = pos->prev;
BHLLNode* posn = pos->next;
free(pos);
pprev->next = posn;
posn->prev = pprev;
}
函数测试
#define _CRT_SECURE_NO_WARNINGS
#include"Bidirectional head-linked list.h"
void test()
{
BHLLNode* head = BHLLInit();
BHLLPushBack(head, 1);
BHLLPushBack(head, 2);
BHLLPushBack(head, 3);
BHLLPushBack(head, 4);
BHLLPushBack(head, 5);
BHLLPushBack(head, 6);
BHLLPushBack(head, 7);
BHLLPushBack(head, 8);
BHLLPrint(head);
BHLLPushFront(head, -1);
BHLLPushFront(head, -2);
BHLLPushFront(head, -3);
BHLLPushFront(head, -4);
BHLLPushFront(head, -5);
BHLLPushFront(head, -6);
BHLLPushFront(head, -7);
BHLLPushFront(head, -8);
BHLLPrint(head);
BHLLPopBack(head);
BHLLPopBack(head);
BHLLPrint(head);
BHLLPopFront(head);
BHLLPopFront(head);
BHLLPrint(head);
BHLLNode* ret = BHLLFnind(head,1);
BHLLInsert(ret, 6);
BHLLErase(ret);
BHLLPrint(head);
ret = BHLLFnind(head, -1);
BHLLInsert(ret, 6);
BHLLErase(ret);
BHLLPrint(head);
BHLLPrint(head);
BHLLDestroy(head);
}
int main()
{
test();
}
顺序表在数据的读取上更占优势,CPU在寄存器上一次访问几十个字节(连续的),顺序表的存储连续使得CPU能一次访问多的有效数据,而链表的数据存储时离散的,使得CPU在寄存器上一次访问的几十字节中不一定全是有效的数据,且造成缓存的污染。
栈:
封装一层将头指针与尾指针放在同一结构体中,使得传该结构体的指针就能修改头指针与尾指针。
oj
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
方法一:找到相遇节点后,打断节点以找相交链表的节点方式找入环节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
struct ListNode *cura=headA,*curb=headB;
int lena=0,lenb=0;
while(cura->next)
{
lena++;
cura=cura->next;
}
while(curb->next)
{
lenb++;
curb=curb->next;
}
if(cura!=curb)
{
return NULL;
}
struct ListNode * longlist=headA;
struct ListNode * shortlist=headB;
if(lena<lenb)
{
longlist=headB;
shortlist=headA;
}
int gap=abs(lena-lenb);
while(gap--)
{
longlist=longlist->next;
}
while(longlist!=shortlist)
{
longlist=longlist->next;
shortlist=shortlist->next;
}
return longlist ;
}
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode * fast,*slow,*last;
fast=slow=last=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
struct ListNode* meet=slow;
struct ListNode* newhead=meet->next;
meet->next=NULL;
return getIntersectionNode(newhead,head);
}
}
return NULL;
}
方法二:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode * fast,*slow,*last;
fast=slow=last=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
while(last!=fast)
{
last=last->next;
fast=fast->next;
}
return last;
}
}
return NULL;
}