链表由一系列不必在内存中相连的节点组成,分为单链,双链和循环链表。
根据链表的存储特点可以得出链表的特点:可以快捷的进行插入和删除操作,但是查找操作费时。
主要复习下单链表。已c实现单链表的insert,delete等操作。
链表C语言实现:
//单链 struct listNode
{
int data;
listNode* next;
};
//在链表position位置前插入节点。
int insert(listNode *root,int value,int position)
{
listNode *p,*s;
p = root;
int j = 1;
while(p&&j<position)
{
p = p->next;
++j;
}
if(p==NULL|| j>position)
{
return -1;
}
//s = (listNode*)new(listNode);
s = (listNode*)malloc(sizeof(*root));
if(s==NULL)
{
return -1;
}
s->data = value;
s->next = p->next;
p->next = s;
return 1;
}
//删除position位置的元素,并由value返回其值
int deleteNode(listNode *root,int position,int &value)
{
int j = 1;
listNode *p,*q;
p=root;
while(p&&j<position)
{
p = p->next;
++j;
}
if((p->next)==NULL||j>position)
{
return -1;
}
q = p->next;
p->next =q->next;
value = q->data;
free(q);
return 1;
}
//删除给定的节点
void deleteNode(listNode *node)
{
assert(node != NULL);
listNode * nxt = node->next;
if(nxt != NULL)
{
node->data = nxt->data;
node->next = nxt->next;
delete nxt;
return;
}
delete node;
}
//单链表反转
listNode* RevlistNode(listNode * root)
{
if(root == NULL)
{
return NULL;
}
if(root->next == NULL)
{
return root;
}
listNode *cur,*pre,*nxt;
pre= NULL;
cur = root;
while(cur)
{
nxt = cur->next;
cur->next = pre;
pre = cur;
cur=nxt;
}
return pre;
}
1.单链表反转。
以微软的一道面试题为例,编写一个函数,给定一个链表的头指针,要求只遍历一次,将单链表中的元素顺序反转过来。
给出反转函数:
Node* LinkList_reverse(Node* head) { Node *preNode,*curNode,*nextNode; if(head==NULL) return NULL;//空链表 if(head->next == NULL) return head;//仅一个元素 curNode = head;preNode=NULL;//初始化 while(curNode) { nextNode = curNode->next;//先记录下一个结点 curNode->next = preNode;//改变链表方向(逆置) preNode = curNode;//将当前结点作为下一次循环的前一个结点 curNode = nextNode;//向后推移一个结点 } return preNode;//当遍历完链表后curNode应该为空,此时preNode链表头(head) }
2.链表添加节点
//在给定的节点前插入新节点 void LinkList_Add(Node* ptr,Node* newNode) { int temp = 0; newNode->next = ptr->next; ptr->next = newNode; temp = ptr->e; ptr->e = newNode->e; newNode->e = temp; }
3.无头链表删除给定节点
同样以一面试题为例
假设一个没有头指针的单链表,一个指针指向此单链表中间的一个节点(非第一个或最后一个节点),请将该节点删除。
//删除节点 void LinkList_Delete(Node* ptr) { Node* temp = ptr->next; if(temp != NULL) { ptr->e = temp->e; ptr->next = temp->next; delete temp;//这里delete好像有问题,以后再看下 } }