单链表的基本操作(一)

来源:互联网 发布:如何进入投行 知乎 编辑:程序博客网 时间:2024/05/16 12:48

单链表在插入、删除时较为方便,平时做题或者面试也会遇到很多,下面对单链表的操作做一些介绍。

本文参考了一些blog,不过只记得下面这个啦:

http://blog.csdn.net/puqutogether/article/details/39990419


定义一个结构体

struct Node{int data;Node* next;};
在 运算前先定义一个全局变量 head:

Node* head=NULL;


1.创建一个有头结点的链表

bool CreateLink()//创建链表{head=new Node;if(head==NULL)return false;else{head->data=0;head->next=NULL;return true;}}
2.增加节点
bool AddNode(Node *addNode)//增加节点{Node *p=head->next;Node *q=head;while(p!=NULL)//往后查找,直到找到最后的位置{q=p;p=p->next;}q->next=addNode;addNode->next=NULL;return true;}
3.计算节点总数

int CountNode()//计算节点{Node *p=head->next;int count=0;while(p!=NULL){count++;p=p->next;}return count;}

4.查找节点

int Search(int x)//查找节点的元素值为x的下标{Node *p=head->next;for(int j=1;p&&p->data!=x;j++)p=p->next;if(p)return j;return -1;}
5.插入节点

bool Insert(int i,int x)//在a[i]节点后面插入x(节点从a[0]开始标记){Node *p=head;for(int j=0; j<=i; j++)p=p->next;Node *q=new Node;q->data=x;q->next=p->next;//在p后面插入q,无需区分头结点和一般节点p->next=q;return true;}
6.删除节点

bool Delete(int i)//删除第i个节点{Node *q=head,*p;for(int j=0; j<i; j++){q=q->next;}p=q->next;q->next=p->next;delete p;return true;}
7.链表反转


每次都将第一个节点之后的节点放在head后面。tmp指向第一个节点,p指向第二个节点,再把第二个节点放在head与第一个节点之间,就完成了第一次交换,顺序就变成了Head-结点2-结点1-结点3-结点4-NULL。同样下次再把结点3放在head与结点之间,以此类推。

void ReverseLink()//链表反转{        Node *tmp=NULL;Node *p=NULL;tmp=head->next;while(tmp->next!=NULL){p=tmp->next;tmp->next=p->next;p->next=head->next;head->next=p;}}

8.查找倒数第k个节点

给两个指针p和q,让其中一个指针p领先q指针k步,然后再同时移动p和q指针,当领先的指针p先到达链表尾部时,后面的指针q所指向的节点恰好为倒数第k个节点。

Node* GetKthNode(int k){Node *p=head;Node *q=head;while(k>1 && p->next!=NULL){p=p->next;k--;}if(k>1 || p==NULL)return NULL;while(p->next!=NULL){q=q->next;p=p->next;}return q;}

9.判断链表是否成环

 这里使用两个指针q和p,一个指针走两步(p),一个指针走一步(q)。如果成环,两个指针会在O(n)内相遇 ,否则先走的会指向空。

bool Iscircle(Node *head)//判断是否有环{   Node *p=head;   Node *q=head;   while(p!=NULL && p->next!=NULL)   {   p=p->next->next;   q=q->next;   if(p==q)          return true;   }   return false;}







0 0